﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TileEditorApplication.TileClasses;
using TileEditorApplication.TriggerClasses;
using System.Xml.Linq;

using SGD;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;


namespace TileEditorApplication
{
    public partial class Form1 : Form
    {
        //added-LL
        struct TextureVertex
        {
            public Vector3 Pos;
            public Vector2 TexCoord;

            public TextureVertex(Vector3 _Pos, float texx, float texy)
            {
                Pos = _Pos;
                TexCoord.X = texx;
                TexCoord.Y = texy;
            }
        }

        struct VisibleLight
        {
            public float[] lightPos;
            public float[] lightRadius;
            public float lightIntensity;
            public float[] lightColor;

            public VisibleLight(float lightPositionX = 0)
            {
                lightPos = new float[2];
                lightRadius = new float[2];
                lightColor = new float[4];

                lightIntensity = 0.0f;

                lightPos[0] = -1000.0f;
                lightPos[1] = -1000.0f;

                lightRadius[0] = 0.0f;
                lightRadius[1] = 0.0f;

                lightColor[0] = 0.0f;
                lightColor[1] = 0.0f;
                lightColor[2] = 0.0f;
                lightColor[3] = 0.0f;
            }
        }

        List<Light> lights = new List<Light>();
        bool lightToolSelected;
        int lightSelected = -1;
        int lightIconID = -1;
        int lightSelectedIconID = -1;

        VisibleLight[] visibleLight;

        float ambientIntensity;
        float[] ambientColor;

        Surface previous, output;
        Texture snapshot;
        VertexBuffer vertexBuffer;
        VertexDeclaration vertexDecl;
        Effect postProcessEffect;
        //end added - LL

        ManagedDirect3D D3D = ManagedDirect3D.Instance;
        ManagedTextureManager TM = ManagedTextureManager.Instance;

        Map map;

        Cursor pan = new Cursor("cursors/pan.cur");
        Cursor select = new Cursor("cursors/select.cur");
        Cursor paintBrush = new Cursor("cursors/paint_brush.cur");
        Cursor paintBucket = new Cursor("cursors/paint_bucket.cur");
        Cursor zoomIn = new Cursor("cursors/zoom_in.cur");
        Cursor zoomOut = new Cursor("cursors/zoom_out.cur");
        Cursor eraser = new Cursor("cursors/eraser.cur");
        Cursor add = new Cursor("cursors/add.cur");
        Cursor remove = new Cursor("cursors/remove.cur");
        Cursor rotate = new Cursor("cursors/rotate.cur");

        List<TileSet> tileSets = new List<TileSet>();
        List<Object> availableObjects = new List<Object>();

        List<Object> props = new List<Object>();
        List<Object> enemies = new List<Object>();
        List<Object> powerups = new List<Object>();

        List<EventTrigger> eventTriggers = new List<EventTrigger>();
        List<Trigger> collisionTriggers = new List<Trigger>();
        List<SpawnTrigger> spawnTriggers = new List<SpawnTrigger>();
        List<SpawnPoint> playerSpawnPoints = new List<SpawnPoint>();

        Bitmap tilesetSelected = new Bitmap("custom/tile_selected.png");
        Bitmap tilesetNotSelected = new Bitmap("custom/tile_notselected.png");

        bool isPanning = false;
        bool isMouseDown = false;
        bool isSpawnSelected = false;

        int noTile = -1;
        int gridTile = -1;
        int selectedTileset = 0;
        int selectedObject = -1;
        int selectedProp = -1;
        int selectedEnemy = -1;
        int selectedPowerup = -1;
        int mapWidth;
        int mapHeight;
        int tileWidth;
        int tileHeight;
        int spawnPoint = -1;
        int spawnTrigger = -1;
        int eventTrigger = -1;
        int collisionTrigger = -1;
        int playerSpawn = -1;

        int collisionCount = 0;
        int eventCount = 0;
        int spawnCount = 0;

        float scale = 1.0f;

        Point selectedSourceTile = new Point(-1, -1);
        Point panPoint = Point.Empty;
        Point auxPos = Point.Empty;

        string filePath;

        public Form1()
        {
            InitializeComponent();

            D3D.InitManagedDirect3D(this.AppContainer.Panel1,this.AppContainer.Panel1.Width - 20, this.AppContainer.Panel1.Height - 20,true, false);
            TM.InitManagedTextureManager(D3D.Device, D3D.Sprite);

            map = new Map(25, 25, 64,64);

            noTile = TM.LoadTexture("tiles/notile64x64.jpg",0);
            gridTile = TM.LoadTexture("tiles/gridblock.png", 0);
            spawnPoint = TM.LoadTexture("custom/spawn_point.png", 0);
            spawnTrigger = TM.LoadTexture("custom/spawn_trigger.png", 0);
            eventTrigger = TM.LoadTexture("custom/event_trigger.png", 0);
            collisionTrigger = TM.LoadTexture("custom/collision_trigger.png", 0);
            playerSpawn = TM.LoadTexture("custom/player_spawn.png", 0);
         
            mapWidth = map.mapSize.Width;
            mapHeight = map.mapSize.Height;
            tileWidth = map.tileSize.Width;
            tileHeight = map.tileSize.Height;            

            TileWidthUpDown.Value = tileWidth;
            TileHeightUpDown.Value = tileHeight;
            MapWidthUpDown.Value = mapWidth;
            MapHeightUpDown.Value = mapHeight;

            AppContainer.Panel1.AutoScrollMinSize = map.GetRect().Size;
            AppContainer.MouseWheel += new System.Windows.Forms.MouseEventHandler(RenderWindowMouseWheelHandle);

            CheckFilePath();

            if (tileSets.Count > 0)
            {
                TilesetNameBox.Text = tileSets[selectedTileset].name;
                TileWidthUpDown1.Value = tileSets[selectedTileset].tileSize.Width;
                TileHeightUpDown1.Value = tileSets[selectedTileset].tileSize.Height;
            }

            //added - LL
            lightIconID = TM.LoadTexture("custom/lighticon.png", 0);
            lightSelectedIconID = TM.LoadTexture("custom/lightselectedicon.png", 0);

            InitQuad();

            visibleLight = new VisibleLight[10];
            visibleLight[0] = new VisibleLight(0);
            visibleLight[1] = new VisibleLight(0);
            visibleLight[2] = new VisibleLight(0);
            visibleLight[3] = new VisibleLight(0);
            visibleLight[4] = new VisibleLight(0);
            visibleLight[5] = new VisibleLight(0);
            visibleLight[6] = new VisibleLight(0);
            visibleLight[7] = new VisibleLight(0);
            visibleLight[8] = new VisibleLight(0);
            visibleLight[9] = new VisibleLight(0);

            ambientColor = new float[4];
            ambientColor[0] = 1.0f;
            ambientColor[1] = 1.0f;
            ambientColor[2] = 1.0f;
            ambientIntensity = 1.0f;
            //end added - LL
        }

        //added -LL
        private void InitQuad()
        {
            vertexBuffer = new VertexBuffer(typeof(TextureVertex), 6, D3D.Device, Usage.WriteOnly, VertexFormats.Position | VertexFormats.Normal | VertexFormats.Texture0, Pool.Managed);
            TextureVertex[] vertices = new TextureVertex[6];
            vertices[0] = new TextureVertex(new Vector3(-1.0f, 1.0f, 0.0f), 0.0f, 0.0f);
            vertices[1] = new TextureVertex(new Vector3(1.0f, 1.0f, 0.0f), 1.0f, 0.0f);
            vertices[2] = new TextureVertex(new Vector3(1.0f, -1.0f, 0.0f), 1.0f, 1.0f);

            vertices[3] = new TextureVertex(new Vector3(-1.0f, 1.0f, 0.0f), 0.0f, 0.0f);
            vertices[4] = new TextureVertex(new Vector3(1.0f, -1.0f, 0.0f), 1.0f, 1.0f);
            vertices[5] = new TextureVertex(new Vector3(-1.0f, -1.0f, 0.0f), 0.0f, 1.0f);

            vertexBuffer.SetData(vertices, 0, LockFlags.None);

            VertexElement[] velements = new VertexElement[]
             {
                 new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
                 new VertexElement(0, 12, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
                 VertexElement.VertexDeclarationEnd
             };

            vertexDecl = new VertexDeclaration(D3D.Device, velements);
            //snapshot = new Microsoft.DirectX.Direct3D.Texture(D3D.Device, AppContainer.Panel1.Width, AppContainer.Panel1.Height, 0, Usage.RenderTarget, Format.R5G6B5, Pool.Default);
            string error = "";
            postProcessEffect = Effect.FromFile(D3D.Device, "shader\\PointLightArray.fx", null, null, ShaderFlags.Debug, null, out error);

        }
        //end added - LL

        ///////////////////////
        /////// DRAWING ///////
        ///////////////////////
        public void Render()
        {

            snapshot = new Microsoft.DirectX.Direct3D.Texture(D3D.Device, AppContainer.Panel1.Width, AppContainer.Panel1.Height, 0, Usage.RenderTarget, Format.R5G6B5, Pool.Default);

            output = snapshot.GetSurfaceLevel(0);
            previous = D3D.Device.GetRenderTarget(0);

            D3D.Device.SetRenderTarget(0, output);

            D3D.DeviceBegin();
            D3D.SpriteBegin();
            D3D.Clear(255, 255, 255);

            if (ToggleTileStrip.Checked)
            {
                DrawTiles();
            }

            if (ToggleObjectsContextMenu.Checked)
            {
                DrawObjects();
            }

            DrawLights();

            DrawTriggers();

            D3D.Sprite.Flush();

            D3D.SpriteEnd();
            D3D.DeviceEnd();

            
            D3D.Device.SetRenderTarget(0, previous);
            D3D.Clear(255, 255, 255);
            D3D.DeviceBegin();
            PostProcess();
            D3D.DeviceEnd();

            D3D.Present();
            
            snapshot.Dispose();
        }

        private void PostProcess()
        {
            LightsVisible();

            D3D.Device.SetStreamSource(0, vertexBuffer, 0);
            D3D.Device.VertexDeclaration = vertexDecl;
            postProcessEffect.Technique = "Simplest";
            postProcessEffect.SetValue("ambientIntensity", ambientIntensity);
            postProcessEffect.SetValue("ambientColor", ambientColor);
            for (int i = 0; i < 10; i++)
            {
                postProcessEffect.SetValue("pointLight[" + i + "].lightPos", visibleLight[i].lightPos);
                postProcessEffect.SetValue("pointLight[" + i + "].lightIntensity", visibleLight[i].lightIntensity);
                postProcessEffect.SetValue("pointLight[" + i + "].lightRadius", visibleLight[i].lightRadius);
                postProcessEffect.SetValue("pointLight[" + i + "].lightColor", visibleLight[i].lightColor);
            }
            postProcessEffect.SetValue("xColoredTexture", snapshot);

            int numpasses = postProcessEffect.Begin(0);
            for (int i = 0; i < numpasses; i++)
            {
                postProcessEffect.BeginPass(i);
                D3D.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
                postProcessEffect.EndPass();
            }
            postProcessEffect.End();
        }

        private void DrawTiles()
        {
            int posX = AppContainer.Panel1.AutoScrollPosition.X;
            int posY = AppContainer.Panel1.AutoScrollPosition.Y;

            int xStart = (int)((-posX / tileWidth) * scale);
            int yStart = (int)((-posY / tileHeight) * scale);

            int xEnd = (int)(((xStart + AppContainer.Panel1.Width / tileWidth) + 1) / scale);
            int yEnd = (int)(((yStart + AppContainer.Panel1.Height / tileHeight) + 1) / scale);

            if (xEnd < mapWidth - 1)
            {
                ++xEnd;
            }
            else
            {
                xEnd = mapWidth;
            }

            if (yEnd < mapHeight - 1)
            {
                ++yEnd;
            }
            else
            {
                yEnd = mapHeight;
            }

            for (int x = xStart; x < xEnd; ++x)
            {
                for (int y = yStart; y < yEnd; ++y)
                {
                    if (map.mapMatrix[x, y].tile.X == -1)
                    {
                        TM.Draw(noTile, (int)((x * tileWidth + posX) * scale),(int)((y * tileHeight + posY) * scale), (tileWidth / (float)TM.GetTextureWidth(noTile)) * scale, (tileHeight / (float)TM.GetTextureHeight(noTile)) * scale, Rectangle.Empty, 0, 0, 0.0f, 0);
                    }
                    else
                    {     

                        Rectangle source = new Rectangle(map.mapMatrix[x, y].tile.X * tileSets[map.tilesetIndex[x, y]].tileSize.Width,
                                                         map.mapMatrix[x, y].tile.Y * tileSets[map.tilesetIndex[x, y]].tileSize.Height,
                                                         tileSets[map.tilesetIndex[x, y]].tileSize.Width, tileSets[map.tilesetIndex[x, y]].tileSize.Height);

                        TM.Draw(map.mapMatrix[x, y].tileSetID, (int)((x * tileWidth + posX) * scale), (int)((y * tileHeight + posY) * scale), (tileWidth / (float)tileSets[map.tilesetIndex[x, y]].tileSize.Width) * scale, (tileHeight / (float)tileSets[map.tilesetIndex[x, y]].tileSize.Height) * scale, source, 0, 0, 0.0f, 0);
                    }

                    if (ToggleGridContext.Checked)
                    {
                        TM.Draw(gridTile, (int)((x * tileWidth + posX) * scale), (int)((y * tileHeight + posY) * scale), (tileWidth / (float)TM.GetTextureWidth(gridTile)) * scale, (tileHeight / (float)TM.GetTextureHeight(gridTile)) * scale, Rectangle.Empty, 0, 0, 0.0f, 0);
                    }

                    if (ToggleCoordsContext.Checked)
                    {
                        string coordinates = x.ToString() + "," + y.ToString();
                        D3D.DrawText(coordinates, (int)((x * tileWidth + posX) * scale), (int)((y * tileHeight + posY) * scale), 255, 0, 0);
                    }
                }
            }
        }

        private void DrawObjects()
        {
            int posX = AppContainer.Panel1.AutoScrollPosition.X;
            int posY = AppContainer.Panel1.AutoScrollPosition.Y;

            for (int i = 0; i < props.Count(); ++i)
            {
                int xCenter = (int)((props[i].size.Width * scale) / 2 );
                int yCenter = (int)((props[i].size.Height * scale) / 2 );

                TM.Draw(props[i].textureID,(int)((props[i].position.X + posX) * scale), 
                       (int)((props[i].position.Y + posY) * scale),
                       (props[i].size.Width / (float)props[i].bitmap.Width) * scale,
                       (props[i].size.Height / (float)props[i].bitmap.Height) * scale,
                       Rectangle.Empty, xCenter, yCenter, DegreeToRadian(props[i].rotation), 0);

                if (selectedProp == i)
                {
                    D3D.Sprite.Flush();
                    D3D.DrawLine((int)((props[i].position.X + posX) * scale), 
                                 (int)((props[i].position.Y + posY) * scale),
                                 (int)(((props[i].position.X + posX) * scale) + (props[i].size.Width * scale)),
                                 (int)((props[i].position.Y + posY) * scale), 
                                 255, 0, 0);

                    D3D.DrawLine((int)(((props[i].position.X + posX) * scale) + (props[i].size.Width * scale)), 
                                 (int)((props[i].position.Y + posY) * scale),
                                 (int)(((props[i].position.X + posX) * scale) + (props[i].size.Width * scale)),
                                 (int)(((props[i].position.Y + posY) * scale) + (props[i].size.Height * scale)), 255, 0, 0);

                    D3D.DrawLine((int)((props[i].position.X + posX) * scale), 
                                 (int)(((props[i].position.Y + posY) * scale) + (props[i].size.Height * scale)),
                                 (int)(((props[i].position.X + posX) * scale) + (props[i].size.Width * scale)),
                                 (int)(((props[i].position.Y + posY) * scale) + (props[i].size.Height * scale)), 
                                 255, 0, 0);

                    D3D.DrawLine((int)((props[i].position.X + posX) * scale), 
                                 (int)((props[i].position.Y + posY) * scale),
                                 (int)(((props[i].position.X + posX) * scale)),
                                 (int)(((props[i].position.Y + posY) * scale) + (props[i].size.Height * scale)), 
                                 255, 0, 0);
                }
            }

            for (int i = 0; i < enemies.Count(); ++i)
            {
                int xCenter = (int)((enemies[i].size.Width * scale) / 2);
                int yCenter = (int)((enemies[i].size.Height * scale) / 2);

                TM.Draw(enemies[i].textureID, (int)((enemies[i].position.X + posX) * scale), 
                       (int)((enemies[i].position.Y + posY) * scale),
                       (enemies[i].size.Width / (float)enemies[i].bitmap.Width) * scale,
                       (enemies[i].size.Height / (float)enemies[i].bitmap.Height) * scale,
                       Rectangle.Empty, xCenter, yCenter, DegreeToRadian(enemies[i].rotation), 0);

                if (selectedEnemy == i)
                {
                    D3D.Sprite.Flush();
                    D3D.DrawLine((int)((enemies[i].position.X + posX) * scale),
                                 (int)((enemies[i].position.Y + posY) * scale),
                                 (int)(((enemies[i].position.X + posX) * scale) + (enemies[i].size.Width * scale)),
                                 (int)((enemies[i].position.Y + posY) * scale),
                                 255, 0, 0);

                    D3D.DrawLine((int)(((enemies[i].position.X + posX) * scale) + (enemies[i].size.Width * scale)),
                                 (int)((enemies[i].position.Y + posY) * scale),
                                 (int)(((enemies[i].position.X + posX) * scale) + (enemies[i].size.Width * scale)),
                                 (int)(((enemies[i].position.Y + posY) * scale) + (enemies[i].size.Height * scale)), 255, 0, 0);

                    D3D.DrawLine((int)((enemies[i].position.X + posX) * scale),
                                 (int)(((enemies[i].position.Y + posY) * scale) + (enemies[i].size.Height * scale)),
                                 (int)(((enemies[i].position.X + posX) * scale) + (enemies[i].size.Width * scale)),
                                 (int)(((enemies[i].position.Y + posY) * scale) + (enemies[i].size.Height * scale)),
                                 255, 0, 0);

                    D3D.DrawLine((int)((enemies[i].position.X + posX) * scale),
                                 (int)((enemies[i].position.Y + posY) * scale),
                                 (int)(((enemies[i].position.X + posX) * scale)),
                                 (int)(((enemies[i].position.Y + posY) * scale) + (enemies[i].size.Height * scale)),
                                 255, 0, 0);
                }
            }

            for (int i = 0; i < powerups.Count(); ++i)
            {
                int xCenter = (int)((powerups[i].size.Width * scale) / 2);
                int yCenter = (int)((powerups[i].size.Height * scale) / 2);

                TM.Draw(powerups[i].textureID, (int)((powerups[i].position.X + posX) * scale), 
                        (int)((powerups[i].position.Y + posY) * scale),
                        (powerups[i].size.Width / (float)powerups[i].bitmap.Width) * scale,
                        (powerups[i].size.Height / (float)powerups[i].bitmap.Height) * scale,
                        Rectangle.Empty, xCenter, yCenter, DegreeToRadian(powerups[i].rotation), 0);

                if (selectedPowerup == i)
                {
                    D3D.Sprite.Flush();
                    D3D.DrawLine((int)((powerups[i].position.X + posX) * scale),
                                 (int)((powerups[i].position.Y + posY) * scale),
                                 (int)(((powerups[i].position.X + posX) * scale) + (powerups[i].size.Width * scale)),
                                 (int)((powerups[i].position.Y + posY) * scale),
                                 255, 0, 0);

                    D3D.DrawLine((int)(((powerups[i].position.X + posX) * scale) + (powerups[i].size.Width * scale)),
                                 (int)((powerups[i].position.Y + posY) * scale),
                                 (int)(((powerups[i].position.X + posX) * scale) + (powerups[i].size.Width * scale)),
                                 (int)(((powerups[i].position.Y + posY) * scale) + (powerups[i].size.Height * scale)), 255, 0, 0);

                    D3D.DrawLine((int)((powerups[i].position.X + posX) * scale),
                                 (int)(((powerups[i].position.Y + posY) * scale) + (powerups[i].size.Height * scale)),
                                 (int)(((powerups[i].position.X + posX) * scale) + (powerups[i].size.Width * scale)),
                                 (int)(((powerups[i].position.Y + posY) * scale) + (powerups[i].size.Height * scale)),
                                 255, 0, 0);

                    D3D.DrawLine((int)((powerups[i].position.X + posX) * scale),
                                 (int)((powerups[i].position.Y + posY) * scale),
                                 (int)(((powerups[i].position.X + posX) * scale)),
                                 (int)(((powerups[i].position.Y + posY) * scale) + (powerups[i].size.Height * scale)),
                                 255, 0, 0);
                }
            }
        }

        private void DrawTriggers()
        {
            int posX = AppContainer.Panel1.AutoScrollPosition.X;
            int posY = AppContainer.Panel1.AutoScrollPosition.Y;

            if (ToggleCollisionContext.Checked)
            {
                for (int i = 0; i < collisionTriggers.Count(); ++i)
                {
                    float scaleX = (collisionTriggers[i].size.Width / (float)TM.GetTextureWidth(collisionTrigger)) * scale;
                    float scaleY = (collisionTriggers[i].size.Height / (float)TM.GetTextureHeight(collisionTrigger)) * scale;

                    TM.Draw(collisionTrigger, (int)(collisionTriggers[i].position.X * scale) + posX, (int)(collisionTriggers[i].position.Y * scale) + posY,
                            scaleX, scaleY, Rectangle.Empty, 0, 0, 0, 0);

                    if (CollisionRadioButton.Checked && CollisionComboBox.SelectedIndex == i)
                    {
                        D3D.Sprite.Flush();
                        D3D.DrawLine((int)((collisionTriggers[i].position.X + posX) * scale),
                                     (int)((collisionTriggers[i].position.Y + posY) * scale),
                                     (int)(((collisionTriggers[i].position.X + posX) * scale) + (collisionTriggers[i].size.Width * scale)),
                                     (int)((collisionTriggers[i].position.Y + posY) * scale),
                                     0, 255, 0);

                        D3D.DrawLine((int)(((collisionTriggers[i].position.X + posX) * scale) + (collisionTriggers[i].size.Width * scale)),
                                     (int)((collisionTriggers[i].position.Y + posY) * scale),
                                     (int)(((collisionTriggers[i].position.X + posX) * scale) + (collisionTriggers[i].size.Width * scale)),
                                     (int)(((collisionTriggers[i].position.Y + posY) * scale) + (collisionTriggers[i].size.Height * scale)), 0, 255, 0);

                        D3D.DrawLine((int)((collisionTriggers[i].position.X + posX) * scale),
                                     (int)(((collisionTriggers[i].position.Y + posY) * scale) + (collisionTriggers[i].size.Height * scale)),
                                     (int)(((collisionTriggers[i].position.X + posX) * scale) + (collisionTriggers[i].size.Width * scale)),
                                     (int)(((collisionTriggers[i].position.Y + posY) * scale) + (collisionTriggers[i].size.Height * scale)),
                                     0, 255, 0);

                        D3D.DrawLine((int)((collisionTriggers[i].position.X + posX) * scale),
                                     (int)((collisionTriggers[i].position.Y + posY) * scale),
                                     (int)(((collisionTriggers[i].position.X + posX) * scale)),
                                     (int)(((collisionTriggers[i].position.Y + posY) * scale) + (collisionTriggers[i].size.Height * scale)),
                                     0, 255, 0);
                    }
                }
            }


            if (ToggleEventContext.Checked)
            {
                for (int i = 0; i < eventTriggers.Count(); ++i)
                {
                    float scaleX = (eventTriggers[i].size.Width / (float)TM.GetTextureWidth(eventTrigger)) * scale;
                    float scaleY = (eventTriggers[i].size.Height / (float)TM.GetTextureHeight(eventTrigger)) * scale;

                    TM.Draw(eventTrigger, (int)(eventTriggers[i].position.X * scale) + posX, (int)(eventTriggers[i].position.Y * scale) + posY,
                            scaleX, scaleY, Rectangle.Empty, 0, 0, 0, 0);

                    if (EventRadioButton.Checked && EventComboBox.SelectedIndex == i)
                    {
                        D3D.Sprite.Flush();
                        D3D.DrawLine((int)((eventTriggers[i].position.X + posX) * scale),
                                     (int)((eventTriggers[i].position.Y + posY) * scale),
                                     (int)(((eventTriggers[i].position.X + posX) * scale) + (eventTriggers[i].size.Width * scale)),
                                     (int)((eventTriggers[i].position.Y + posY) * scale),
                                     255, 0, 0);

                        D3D.DrawLine((int)(((eventTriggers[i].position.X + posX) * scale) + (eventTriggers[i].size.Width * scale)),
                                     (int)((eventTriggers[i].position.Y + posY) * scale),
                                     (int)(((eventTriggers[i].position.X + posX) * scale) + (eventTriggers[i].size.Width * scale)),
                                     (int)(((eventTriggers[i].position.Y + posY) * scale) + (eventTriggers[i].size.Height * scale)), 255, 0, 0);

                        D3D.DrawLine((int)((eventTriggers[i].position.X + posX) * scale),
                                     (int)(((eventTriggers[i].position.Y + posY) * scale) + (eventTriggers[i].size.Height * scale)),
                                     (int)(((eventTriggers[i].position.X + posX) * scale) + (eventTriggers[i].size.Width * scale)),
                                     (int)(((eventTriggers[i].position.Y + posY) * scale) + (eventTriggers[i].size.Height * scale)),
                                     255, 0, 0);

                        D3D.DrawLine((int)((eventTriggers[i].position.X + posX) * scale),
                                     (int)((eventTriggers[i].position.Y + posY) * scale),
                                     (int)(((eventTriggers[i].position.X + posX) * scale)),
                                     (int)(((eventTriggers[i].position.Y + posY) * scale) + (eventTriggers[i].size.Height * scale)),
                                     255, 0, 0);
                    }
                }
            }

            if (ToggleSpawnContext.Checked)
            {
                for (int i = 0; i < spawnTriggers.Count(); ++i)
                {
                    float scaleX = (spawnTriggers[i].size.Width / (float)TM.GetTextureWidth(spawnTrigger)) * scale;
                    float scaleY = (spawnTriggers[i].size.Height / (float)TM.GetTextureHeight(spawnTrigger)) * scale;

                    TM.Draw(spawnTrigger, (int)(spawnTriggers[i].position.X * scale) + posX, (int)(spawnTriggers[i].position.Y * scale) + posY,
                            scaleX, scaleY, Rectangle.Empty, 0, 0, 0, 0);

                    scaleX = (spawnTriggers[i].spawnSize.Width / (float)TM.GetTextureWidth(spawnPoint)) * scale;
                    scaleY = (spawnTriggers[i].spawnSize.Height / (float)TM.GetTextureHeight(spawnPoint)) * scale;

                    TM.Draw(spawnPoint, (int)(spawnTriggers[i].spawnPoint.X * scale) + posX, (int)(spawnTriggers[i].spawnPoint.Y * scale) + posY,
                            scaleX, scaleY, Rectangle.Empty, 0, 0, 0, 0);

                    if (SpawnRadioButton.Checked && SpawnComboBox.SelectedIndex == i)
                    {
                        D3D.Sprite.Flush();
                        D3D.DrawLine((int)((spawnTriggers[i].position.X + posX) * scale),
                                     (int)((spawnTriggers[i].position.Y + posY) * scale),
                                     (int)(((spawnTriggers[i].position.X + posX) * scale) + (spawnTriggers[i].size.Width * scale)),
                                     (int)((spawnTriggers[i].position.Y + posY) * scale),
                                     255, 0, 0);

                        D3D.DrawLine((int)(((spawnTriggers[i].position.X + posX) * scale) + (spawnTriggers[i].size.Width * scale)),
                                     (int)((spawnTriggers[i].position.Y + posY) * scale),
                                     (int)(((spawnTriggers[i].position.X + posX) * scale) + (spawnTriggers[i].size.Width * scale)),
                                     (int)(((spawnTriggers[i].position.Y + posY) * scale) + (spawnTriggers[i].size.Height * scale)), 255, 0, 0);

                        D3D.DrawLine((int)((spawnTriggers[i].position.X + posX) * scale),
                                     (int)(((spawnTriggers[i].position.Y + posY) * scale) + (spawnTriggers[i].size.Height * scale)),
                                     (int)(((spawnTriggers[i].position.X + posX) * scale) + (spawnTriggers[i].size.Width * scale)),
                                     (int)(((spawnTriggers[i].position.Y + posY) * scale) + (spawnTriggers[i].size.Height * scale)),
                                     255, 0, 0);

                        D3D.DrawLine((int)((spawnTriggers[i].position.X + posX) * scale),
                                     (int)((spawnTriggers[i].position.Y + posY) * scale),
                                     (int)(((spawnTriggers[i].position.X + posX) * scale)),
                                     (int)(((spawnTriggers[i].position.Y + posY) * scale) + (spawnTriggers[i].size.Height * scale)),
                                     255, 0, 0);

                        D3D.DrawLine((int)((spawnTriggers[i].spawnPoint.X + posX) * scale),
                                     (int)((spawnTriggers[i].spawnPoint.Y + posY) * scale),
                                     (int)(((spawnTriggers[i].spawnPoint.X + posX) * scale) + (spawnTriggers[i].spawnSize.Width * scale)),
                                     (int)((spawnTriggers[i].spawnPoint.Y + posY) * scale),
                                     255, 0, 0);

                        D3D.DrawLine((int)(((spawnTriggers[i].spawnPoint.X + posX) * scale) + (spawnTriggers[i].spawnSize.Width * scale)),
                                     (int)((spawnTriggers[i].spawnPoint.Y + posY) * scale),
                                     (int)(((spawnTriggers[i].spawnPoint.X + posX) * scale) + (spawnTriggers[i].spawnSize.Width * scale)),
                                     (int)(((spawnTriggers[i].spawnPoint.Y + posY) * scale) + (spawnTriggers[i].spawnSize.Height * scale)), 255, 0, 0);

                        D3D.DrawLine((int)((spawnTriggers[i].spawnPoint.X + posX) * scale),
                                     (int)(((spawnTriggers[i].spawnPoint.Y + posY) * scale) + (spawnTriggers[i].spawnSize.Height * scale)),
                                     (int)(((spawnTriggers[i].spawnPoint.X + posX) * scale) + (spawnTriggers[i].spawnSize.Width * scale)),
                                     (int)(((spawnTriggers[i].spawnPoint.Y + posY) * scale) + (spawnTriggers[i].spawnSize.Height * scale)),
                                     255, 0, 0);

                        D3D.DrawLine((int)((spawnTriggers[i].spawnPoint.X + posX) * scale),
                                     (int)((spawnTriggers[i].spawnPoint.Y + posY) * scale),
                                     (int)(((spawnTriggers[i].spawnPoint.X + posX) * scale)),
                                     (int)(((spawnTriggers[i].spawnPoint.Y + posY) * scale) + (spawnTriggers[i].spawnSize.Height * scale)),
                                     255, 0, 0);

                        D3D.DrawLine((int)(((spawnTriggers[i].spawnPoint.X + posX) * scale) + ((spawnTriggers[i].spawnSize.Width / 2.0f) * scale)),
                                     (int)(((spawnTriggers[i].spawnPoint.Y + posY) * scale) + ((spawnTriggers[i].spawnSize.Height / 2.0f) * scale)),
                                     (int)(((spawnTriggers[i].position.X + posX) * scale) + ((spawnTriggers[i].size.Width / 2.0f) * scale)),
                                     (int)(((spawnTriggers[i].position.Y + posY) * scale) + ((spawnTriggers[i].size.Height / 2.0f) * scale)),
                                     255, 0, 0);
                    }
                }

                for (int i = 0; i < playerSpawnPoints.Count(); ++i)
                {
                    float scaleX = scale;
                    float scaleY = scale;

                    TM.Draw(playerSpawn, (int)(playerSpawnPoints[i].position.X * scale) + posX, (int)(playerSpawnPoints[i].position.Y * scale) + posY,
                            scaleX, scaleY, Rectangle.Empty, 0, 0, 0, 0);

                    if (PlayerSpawnRadio.Checked && PlayerSpawnComboBox.SelectedIndex == i)
                    {
                        D3D.Sprite.Flush();
                        D3D.DrawLine((int)((playerSpawnPoints[i].position.X + posX) * scale),
                                     (int)((playerSpawnPoints[i].position.Y + posY) * scale),
                                     (int)(((playerSpawnPoints[i].position.X + posX) * scale) + (TM.GetTextureWidth(playerSpawn) * scale)),
                                     (int)((playerSpawnPoints[i].position.Y + posY) * scale),
                                     255, 0, 0);

                        D3D.DrawLine((int)(((playerSpawnPoints[i].position.X + posX) * scale) + (TM.GetTextureWidth(playerSpawn) * scale)),
                                     (int)((playerSpawnPoints[i].position.Y + posY) * scale),
                                     (int)(((playerSpawnPoints[i].position.X + posX) * scale) + (TM.GetTextureWidth(playerSpawn) * scale)),
                                     (int)(((playerSpawnPoints[i].position.Y + posY) * scale) + (TM.GetTextureHeight(playerSpawn) * scale)), 255, 0, 0);

                        D3D.DrawLine((int)((playerSpawnPoints[i].position.X + posX) * scale),
                                     (int)(((playerSpawnPoints[i].position.Y + posY) * scale) + (TM.GetTextureHeight(playerSpawn) * scale)),
                                     (int)(((playerSpawnPoints[i].position.X + posX) * scale) + (TM.GetTextureWidth(playerSpawn) * scale)),
                                     (int)(((playerSpawnPoints[i].position.Y + posY) * scale) + (TM.GetTextureHeight(playerSpawn) * scale)),
                                     255, 0, 0);

                        D3D.DrawLine((int)((playerSpawnPoints[i].position.X + posX) * scale),
                                     (int)((playerSpawnPoints[i].position.Y + posY) * scale),
                                     (int)(((playerSpawnPoints[i].position.X + posX) * scale)),
                                     (int)(((playerSpawnPoints[i].position.Y + posY) * scale) + (TM.GetTextureHeight(playerSpawn) * scale)),
                                     255, 0, 0);
                    }
                }
            }
        }

        private void TileLayer_Panel1_Paint(object sender, PaintEventArgs e)
        {
            if (tileSets.Count() > 0 )
            {
                TileLayer.Panel1.AutoScrollMinSize = new Size(tileSets[selectedTileset].bitmap.Size.Width, tileSets[selectedTileset].bitmap.Size.Height);

                int posX = TileLayer.Panel1.AutoScrollPosition.X;
                int posY = TileLayer.Panel1.AutoScrollPosition.Y;

                Rectangle source = new Rectangle(0 - posX, 0 - posY, tileSets[selectedTileset].bitmap.Size.Width, tileSets[selectedTileset].bitmap.Size.Height);
                Rectangle dest = new Rectangle(0, 0, tileSets[selectedTileset].bitmap.Size.Width, tileSets[selectedTileset].bitmap.Size.Height);

                e.Graphics.DrawImage(tileSets[selectedTileset].bitmap, dest, source, GraphicsUnit.Pixel);

                int balls = tileSets[selectedTileset].tileSize.Width;

                Pen pen = new Pen(Brushes.Red, 2);
                e.Graphics.DrawRectangle(pen, selectedSourceTile.X * tileSets[selectedTileset].tileSize.Width + posX,
                                         selectedSourceTile.Y * tileSets[selectedTileset].tileSize.Height + posY,
                                         tileSets[selectedTileset].tileSize.Width, tileSets[selectedTileset].tileSize.Height);
            }
        }

        private void TileLayer2_Panel2_Paint(object sender, PaintEventArgs e)
        {
            if (tileSets.Count() > 0)
            {
                int spacing = 4;

                TileLayer2.Panel2.AutoScrollMinSize = new Size(0, (tilesetNotSelected.Height + spacing) * tileSets.Count());

                for (int i = 0; i < tileSets.Count(); ++i)
                {
                    int posY = TileLayer2.Panel2.AutoScrollPosition.Y;

                    Rectangle buttonDest = new Rectangle(0, i * (tilesetNotSelected.Height + spacing) + posY, TileLayer2.Panel2.Width - 20, tilesetNotSelected.Height);

                    if (selectedTileset == i)
                    {
                        e.Graphics.DrawImage(tilesetSelected, buttonDest);
                        e.Graphics.DrawString(tileSets[i].name, new System.Drawing.Font("Arial Black", 10), new SolidBrush(Color.Black), buttonDest.Width / 2, ((buttonDest.Height / 2) - 10 + posY) + (buttonDest.Height + spacing) * i);
                    }
                    else
                    {
                        e.Graphics.DrawImage(tilesetNotSelected, buttonDest);
                        e.Graphics.DrawString(tileSets[i].name, new System.Drawing.Font("Arial", 10), new SolidBrush(Color.Black), buttonDest.Width / 2, ((buttonDest.Height / 2) - 10 + posY) + (buttonDest.Height + spacing) * i);
                    }

                    Rectangle tileDest = new Rectangle(buttonDest.X + 5, buttonDest.Y + 5, (int)(tileSets[i].tileSize.Width * ((buttonDest.Height - 10) / (float)tileSets[i].tileSize.Width)), buttonDest.Height - 10);
                    Rectangle tileSource = new Rectangle(0, 0, tileSets[i].tileSize.Width, tileSets[i].tileSize.Height);
                    e.Graphics.DrawImage(tileSets[i].bitmap, tileDest, tileSource, GraphicsUnit.Pixel);
                }
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            
            int previewTileWidth = (int)(PreviewPanel.Width / (float)mapWidth);
            int previewTileHeight = (int)(PreviewPanel.Width / (float)mapHeight);

            float previewScaleX = PreviewPanel.Width / (float)(tileWidth * mapWidth);
            float previewScaleY = PreviewPanel.Height / (float)(tileWidth * mapHeight);

            for (int x = 0; x < map.mapSize.Width; ++x)
            {
                for (int y = 0; y < map.mapSize.Height; ++y)
                {
                    if (map.mapMatrix[x, y].tile.X != -1)
                    {
                        Rectangle source = new Rectangle(map.mapMatrix[x, y].tile.X * tileSets[selectedTileset].tileSize.Width,
                                                         map.mapMatrix[x, y].tile.Y * tileSets[selectedTileset].tileSize.Height,
                                                         tileSets[selectedTileset].tileSize.Width, tileSets[selectedTileset].tileSize.Height);

                        Rectangle dest = new Rectangle(x * previewTileWidth, y * previewTileHeight, previewTileWidth, previewTileHeight);

                        e.Graphics.DrawImage(tileSets[map.tilesetIndex[x, y]].bitmap, dest, source, GraphicsUnit.Pixel);
                    }
                }
            }
        }

        ///////////////////////
        //// MOUSE ACTIVITY ///
        ///////////////////////
        private void TileLayer_Panel1_MouseClick(object sender, MouseEventArgs e)
        {
            if (tileSets.Count() > 0)
            {
                int posX = TileLayer.Panel1.AutoScrollPosition.X;
                int posY = TileLayer.Panel1.AutoScrollPosition.Y;

                if (e.X - posX < tileSets[selectedTileset].bitmap.Size.Width && e.Y - posY < tileSets[selectedTileset].bitmap.Size.Height)
                {
                    selectedSourceTile.X = (e.X - posX) / tileSets[selectedTileset].tileSize.Width;
                    selectedSourceTile.Y = (e.Y - posY) / tileSets[selectedTileset].tileSize.Height;
                    TileLayer.Panel1.Invalidate();

                    if (!PaintBrushButton.Checked && !PaintBucketButton.Checked)
                    {
                        PaintBrushButton.Checked = true;
                        SelectTileButton.Checked = false;
                        EraserButton.Checked = false;
                    }
                }
            }
        }

        private void AppContainer_Panel1_MouseMove(object sender, MouseEventArgs e)
        {
            AppContainer.Panel2.Focus();

            if (tileSets.Count() > 0 )
            {
                if (e.Button == MouseButtons.Left && selectedSourceTile.X != -1)
                {
                    int posX = AppContainer.Panel1.AutoScrollPosition.X;
                    int posY = AppContainer.Panel1.AutoScrollPosition.Y;

                    int x = (int)((e.X - (posX * scale)) / (tileWidth * scale));
                    int y = (int)((e.Y - (posY * scale)) / (tileHeight * scale));

                    if (x < mapWidth && y < mapHeight && x >= 0 && y >= 0)
                    {
                        if (PaintBrushButton.Checked)
                        {
                            Tile t = new Tile(selectedSourceTile, tileSets[selectedTileset].textureID);

                            map.mapMatrix[x, y] = t;
                            map.tilesetIndex[x, y] = selectedTileset;

                        }
                        else if (EraserButton.Checked)
                        {
                            map.tilesetIndex[x, y] = -1;
                            map.mapMatrix[x, y].tile = new Point(-1, -1);
                            MapSplit.Panel2.Invalidate();
                        }
                    }
                }
            }

            if (e.Button == MouseButtons.Left && MoveObjectButton.Checked)
            {
                int posX = AppContainer.Panel1.AutoScrollPosition.X;
                int posY = AppContainer.Panel1.AutoScrollPosition.Y;

                Point pos = new Point((int)((e.X - posX) / (scale)),
                                        (int)((e.Y - posY) / (scale)));

                if (selectedProp != -1)
                {
                    pos.X -= (int)((props[selectedProp].size.Width * scale) / 2);
                    pos.Y -= (int)((props[selectedProp].size.Height * scale) / 2);

                    if (pos.X < 0)
                    {
                        pos.X = 0;
                    }
                    else if (pos.X + props[selectedProp].size.Width > mapWidth * tileWidth)
                    {
                        pos.X = (mapWidth * tileWidth) - props[selectedProp].size.Width;
                    }

                    if (pos.Y < 0)
                    {
                        pos.Y = 0;
                    }
                    else if (pos.Y + props[selectedProp].size.Height > mapHeight * tileHeight)
                    {
                        pos.Y = (mapHeight * tileHeight) - props[selectedProp].size.Height;
                    }

                    props[selectedProp].position = pos;
                }
                else if (selectedEnemy != -1)
                {
                    pos.X -= (int)((enemies[selectedEnemy].size.Width * scale) / 2);
                    pos.Y -= (int)((enemies[selectedEnemy].size.Height * scale) / 2);

                    if (pos.X < 0)
                    {
                        pos.X = 0;
                    }
                    else if (pos.X + enemies[selectedEnemy].size.Width > mapWidth * tileWidth)
                    {
                        pos.X = (mapWidth * tileWidth) - enemies[selectedEnemy].size.Width;
                    }

                    if (pos.Y < 0)
                    {
                        pos.Y = 0;
                    }
                    else if (pos.Y + enemies[selectedEnemy].size.Height > mapHeight * tileHeight)
                    {
                        pos.Y = (mapHeight * tileHeight) - enemies[selectedEnemy].size.Height;
                    }

                    enemies[selectedEnemy].position = pos;
                }
                else if (selectedPowerup != -1)
                {
                    pos.X -= (int)((powerups[selectedPowerup].size.Width * scale) / 2);
                    pos.Y -= (int)((powerups[selectedPowerup].size.Height * scale) / 2);

                    if (pos.X < 0)
                    {
                        pos.X = 0;
                    }
                    else if (pos.X + powerups[selectedPowerup].size.Width > mapWidth * tileWidth)
                    {
                        pos.X = (mapWidth * tileWidth) - powerups[selectedPowerup].size.Width;
                    }

                    if (pos.Y < 0)
                    {
                        pos.Y = 0;
                    }
                    else if (pos.Y + powerups[selectedPowerup].size.Height > mapHeight * tileHeight)
                    {
                        pos.Y = (mapHeight * tileHeight) - powerups[selectedPowerup].size.Height;
                    }

                    powerups[selectedPowerup].position = pos;
                }
            }
            else if ( e.Button == MouseButtons.Left && SelectTriggerButton.Checked && isMouseDown == true)
            {
                int posX = AppContainer.Panel1.AutoScrollPosition.X;
                int posY = AppContainer.Panel1.AutoScrollPosition.Y;

                Point pos = new Point((int)((e.X - posX) / (scale)),
                                      (int)((e.Y - posY) / (scale)));

                if (CollisionRadioButton.Checked)
                {
                    if (CollisionComboBox.Items.Count > 0)
                    {
                        pos.X -= (int)((collisionTriggers[CollisionComboBox.SelectedIndex].size.Width * scale) / 2);
                        pos.Y -= (int)((collisionTriggers[CollisionComboBox.SelectedIndex].size.Height * scale) / 2);

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        collisionTriggers[CollisionComboBox.SelectedIndex].position = pos;
                    }
                }
                else if (EventRadioButton.Checked)
                {
                    if (EventComboBox.Items.Count > 0)
                    {
                        pos.X -= (int)((eventTriggers[EventComboBox.SelectedIndex].size.Width * scale) / 2);
                        pos.Y -= (int)((eventTriggers[EventComboBox.SelectedIndex].size.Height * scale) / 2);

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        eventTriggers[EventComboBox.SelectedIndex].position = pos;
                    }
                }
                else if (SpawnRadioButton.Checked && isSpawnSelected == false)
                {
                    if (SpawnComboBox.Items.Count > 0)
                    {
                        pos.X -= (int)((spawnTriggers[SpawnComboBox.SelectedIndex].size.Width * scale) / 2);
                        pos.Y -= (int)((spawnTriggers[SpawnComboBox.SelectedIndex].size.Height * scale) / 2);

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        spawnTriggers[SpawnComboBox.SelectedIndex].position = pos;
                    }
                }
                else if (SpawnRadioButton.Checked && isSpawnSelected == true)
                {
                    if (SpawnComboBox.Items.Count > 0)
                    {
                        pos.X -= (int)((TM.GetTextureWidth(spawnPoint) * scale) / 2);
                        pos.Y -= (int)((TM.GetTextureHeight(spawnPoint) * scale) / 2);

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        spawnTriggers[SpawnComboBox.SelectedIndex].spawnPoint = pos;
                    }
                }
                else if (PlayerSpawnRadio.Checked)
                {
                    if (PlayerSpawnComboBox.Items.Count > 0)
                    {
                        pos.X -= (int)((TM.GetTextureWidth(spawnPoint) * scale) / 2);
                        pos.Y -= (int)((TM.GetTextureHeight(spawnPoint) * scale) / 2);

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        playerSpawnPoints[PlayerSpawnComboBox.SelectedIndex].position = pos;
                    }
                }
            }     

            if (e.Button == MouseButtons.Middle)
            {
                if (!isPanning)
                {
                    AppContainer.Panel1.Cursor = pan;
                    isPanning = true;
                    panPoint = new Point(e.X, e.Y);
                }                
            }
            else
            {                
                isPanning = false;

                if (MapTab.SelectedIndex == 1 && PaintBrushButton.Checked)
                {
                    AppContainer.Panel1.Cursor = paintBrush;
                }
                else if (MapTab.SelectedIndex == 1 && PaintBucketButton.Checked)
                {
                    AppContainer.Panel1.Cursor = paintBucket;
                }
                else if (MapTab.SelectedIndex == 1 && EraserButton.Checked)
                {
                    AppContainer.Panel1.Cursor = eraser;
                }
                else if (MapTab.SelectedIndex == 1 && SelectTileButton.Checked)
                {
                    AppContainer.Panel1.Cursor = select;
                }
                else if (MapTab.SelectedIndex == 2 && PlaceObjectButton.Checked)
                {
                    AppContainer.Panel1.Cursor = add;
                }
                else if (MapTab.SelectedIndex == 2 && SelectObjectButton.Checked)
                {
                    AppContainer.Panel1.Cursor = select;
                }
                else if (MapTab.SelectedIndex == 2 && MoveObjectButton.Checked)
                {
                    AppContainer.Panel1.Cursor = pan;
                }
                else if (MapTab.SelectedIndex == 4 && AddTriggerButton.Checked)
                {
                    AppContainer.Panel1.Cursor = add;
                }
                else if (MapTab.SelectedIndex == 4 && SelectTriggerButton.Checked)
                {
                    AppContainer.Panel1.Cursor = select;
                }
                else
                {
                    AppContainer.Panel1.Cursor = Cursors.Arrow;
                }
            }

            if (isPanning)
            {
                auxPos.X += panPoint.X - e.X;
                auxPos.Y += panPoint.Y - e.Y;

                if (auxPos.X < 0)
                {
                    auxPos.X = 0;
                }

                if (auxPos.Y < 0)
                {
                    auxPos.Y = 0;
                }

                AppContainer.Panel1.AutoScrollPosition = auxPos;
                panPoint = new Point(e.X, e.Y);
            }
        }

        private void AppContainer_Panel1_MouseClick(object sender, MouseEventArgs e)
        {
            int posX = AppContainer.Panel1.AutoScrollPosition.X;
            int posY = AppContainer.Panel1.AutoScrollPosition.Y;

            int x = (int)((e.X - (posX * scale)) / (tileWidth * scale));
            int y = (int)((e.Y - (posY * scale)) / (tileHeight * scale));

            if (e.Button != MouseButtons.Middle)
            {
                if (tileSets.Count() > 0)
                {
                    if (x < mapWidth && y < mapHeight && x >= 0 && y >= 0)
                    {
                        if (PaintBrushButton.Checked && selectedSourceTile.X != -1)
                        {
                            Tile t = new Tile(selectedSourceTile, tileSets[selectedTileset].textureID);
                            map.mapMatrix[x, y] = t;
                            map.tilesetIndex[x, y] = selectedTileset;

                            PreviewPanel.Invalidate();
                        }
                        else if (SelectTileButton.Checked)
                        {
                            if (map.tilesetIndex[(e.X - posX) / map.tileSize.Width, (e.Y - posY) / map.tileSize.Height] != -1)
                            {
                                selectedTileset = map.tilesetIndex[x, y];

                                if (map.mapMatrix[x, y].tile != selectedSourceTile)
                                {
                                    selectedSourceTile = map.mapMatrix[x, y].tile;
                                }

                                TileLayer.Panel1.Invalidate();
                                TileLayer2.Panel2.Invalidate();
                            }
                        }
                        else if (PaintBucketButton.Checked && selectedSourceTile.X != -1)
                        {
                            PaintBucketFill(x, y);
                        }
                        else if (EraserButton.Checked)
                        {
                            map.tilesetIndex[x, y] = -1;
                            map.mapMatrix[x, y].tile = new Point(-1, -1);
                            MapSplit.Panel2.Invalidate();
                        }
                    } 
                }
                if (PlaceObjectButton.Checked && ToggleObjectsContextMenu.Checked && selectedObject >= 0)
                {
                    Point pos = new Point((int)(((e.X - posX)/(scale))), 
                                            (int)(((e.Y - posY)/(scale))));

                    pos.X -= (int)((availableObjects[selectedObject].size.Width * scale) / 2);
                    pos.Y -= (int)((availableObjects[selectedObject].size.Height * scale) / 2);
                    
                    if (pos.X < 0)
                    {
                        pos.X = 0;
                    }                        
                    else if (pos.X + availableObjects[selectedObject].size.Width > mapWidth * tileWidth)
                    {
                        pos.X = (mapWidth * tileWidth) - availableObjects[selectedObject].size.Width;
                    }

                    if (pos.Y < 0)
                    {
                        pos.Y = 0;
                    }
                    else if (pos.Y + availableObjects[selectedObject].size.Height > mapHeight * tileHeight)
                    {
                        pos.Y = (mapHeight * tileHeight) - availableObjects[selectedObject].size.Height;
                    }

                    if (PropRadioButton.Checked)
                    {
                        Object newProp = new Object(availableObjects[selectedObject].name, availableObjects[selectedObject].fileName, availableObjects[selectedObject].filePath, availableObjects[selectedObject].size, pos, 0, 0, availableObjects[selectedObject].textureID);
                        props.Add(newProp);
                        selectedProp = props.Count() - 1;
                        selectedEnemy = -1;
                        selectedPowerup = -1;

                        EditObjectXUpDown.Value = props[selectedProp].position.X;
                        EditObjectYUpDown.Value = props[selectedProp].position.Y;
                        EditObjectRotateUpDown.Value = props[selectedProp].rotation;
                    }
                    else if (EnemyRadioButton.Checked)
                    {
                        Object newEnemy = new Object(availableObjects[selectedObject].name, availableObjects[selectedObject].fileName, availableObjects[selectedObject].filePath, availableObjects[selectedObject].size, pos, 0, 0, availableObjects[selectedObject].textureID);
                        enemies.Add(newEnemy);
                        selectedProp = - 1;
                        selectedEnemy = enemies.Count() -1;
                        selectedPowerup = -1;

                        EditObjectXUpDown.Value = enemies[selectedEnemy].position.X;
                        EditObjectYUpDown.Value = enemies[selectedEnemy].position.Y;
                        EditObjectRotateUpDown.Value = enemies[selectedEnemy].rotation;
                    }
                    else if (PowerUpRadioButton.Checked)
                    {
                        Object newPowerUp = new Object(availableObjects[selectedObject].name, availableObjects[selectedObject].fileName, availableObjects[selectedObject].filePath, availableObjects[selectedObject].size, pos, 0, 0, availableObjects[selectedObject].textureID);
                        powerups.Add(newPowerUp);
                        selectedProp = - 1;
                        selectedEnemy = -1;
                        selectedPowerup = powerups.Count() -1;

                        EditObjectXUpDown.Value = powerups[selectedPowerup].position.X;
                        EditObjectYUpDown.Value = powerups[selectedPowerup].position.Y;
                        EditObjectRotateUpDown.Value = powerups[selectedPowerup].rotation;
                    }
                }
                else if (SelectObjectButton.Checked && ToggleObjectsContextMenu.Checked)
                {
                    Point pos = new Point((int)((e.X - posX) / (scale)),
                                            (int)((e.Y - posY) / (scale)));

                    for (int i = 0; i < props.Count(); ++i)
                    {
                        if (pos.X > props[i].position.X && pos.X < (props[i].position.X + props[i].size.Width)
                            && pos.Y > props[i].position.Y && pos.Y < (props[i].position.Y + props[i].size.Height))
                        {
                            selectedProp = i;
                            selectedEnemy = -1;
                            selectedPowerup = -1;                                    

                            EditObjectXUpDown.Value = props[i].position.X;
                            EditObjectYUpDown.Value = props[i].position.Y;
                            EditObjectRotateUpDown.Value = props[i].rotation;

                            return;
                        }
                    }

                    for (int i = 0; i < enemies.Count(); ++i)
                    {
                        if (pos.X > enemies[i].position.X && pos.X < (enemies[i].position.X + enemies[i].size.Width)
                            && pos.Y > enemies[i].position.Y && pos.Y < (enemies[i].position.Y + enemies[i].size.Height))
                        {
                            selectedEnemy = i;
                            selectedProp = -1;
                            selectedPowerup = -1;

                            EditObjectXUpDown.Value = enemies[i].position.X;
                            EditObjectYUpDown.Value = enemies[i].position.Y;
                            EditObjectRotateUpDown.Value = enemies[i].rotation;

                            return;
                        }
                    }

                    for (int i = 0; i < powerups.Count(); ++i)
                    {
                        if (pos.X > powerups[i].position.X && pos.X < (powerups[i].position.X + powerups[i].size.Width)
                            && pos.Y > powerups[i].position.Y && pos.Y < (powerups[i].position.Y + powerups[i].size.Height))
                        {
                            selectedPowerup = i;
                            selectedEnemy = -1;
                            selectedProp = -1;

                            EditObjectXUpDown.Value = powerups[i].position.X;
                            EditObjectYUpDown.Value = powerups[i].position.Y;
                            EditObjectRotateUpDown.Value = powerups[i].rotation;

                            return;
                        }
                    }
                }
                else if (lightToolSelected)
                {
                    lightPlacement(e);
                }                

                if (AddTriggerButton.Checked)
                {
                    Point pos = new Point((int)(((e.X - posX) / (scale))),
                                          (int)(((e.Y - posY) / (scale))));

                    if(CollisionRadioButton.Checked)
                    {
                        Size s = new Size(TM.GetTextureWidth(collisionTrigger), TM.GetTextureHeight(collisionTrigger));

                        pos.X -= (int)(s.Width/ 2.0f );
                        pos.Y -= (int)(s.Height / 2.0f );

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        Trigger collision = new Trigger("Collision", pos, s, collisionCount++);

                        collisionTriggers.Add(collision);

                        string comboText = "Collision " + collisionCount;
                        CollisionComboBox.Items.Add(comboText);
                        CollisionComboBox.SelectedIndex = collisionTriggers.Count()-1;

                        CollisionXUpDown.Value = pos.X;
                        CollisionYUpDown.Value = pos.Y;
                        CollisionWidthUpDown.Value = s.Width;
                        CollisionHeightUpDown.Value = s.Height;
                    }
                    else if (EventRadioButton.Checked)
                    {
                        Size s = new Size(TM.GetTextureWidth(eventTrigger), TM.GetTextureHeight(eventTrigger));

                        pos.X -= (int)(s.Width / 2.0f);
                        pos.Y -= (int)(s.Height / 2.0f);

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        EventTrigger tempEvent = new EventTrigger("Event", pos, s, eventCount++);

                        eventTriggers.Add(tempEvent);

                        string comboText = "Event " + eventCount;

                        EventComboBox.Items.Add(comboText);
                        EventComboBox.SelectedIndex = eventTriggers.Count() - 1;

                        EventXUpDown.Value = pos.X;
                        EventYUpDown.Value = pos.Y;
                        EventWidthUpDown.Value = s.Width;
                        EventHeightUpDown.Value = s.Height;
                        EventTextBox.Text = "Event";
                        RepeatCheckBox.Checked = false;
                    }
                    else if (SpawnRadioButton.Checked)
                    {
                        Size s = new Size(TM.GetTextureWidth(spawnTrigger), TM.GetTextureHeight(spawnTrigger));
                        Size spawnSize = new Size(TM.GetTextureWidth(spawnPoint), TM.GetTextureHeight(spawnPoint));

                        Point spawnPos = pos;

                        pos.X -= (int)(s.Width / 2.0f);
                        pos.Y -= (int)(s.Height / 2.0f);

                        spawnPos.X -= (int)(spawnSize.Width / 2.0f);
                        spawnPos.Y -= (int)(spawnSize.Height / 2.0f);

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        if (spawnPos.X < 0)
                        {
                            spawnPos.X = 0;
                        }

                        if (spawnPos.Y < 0)
                        {
                            spawnPos.Y = 0;
                        } 

                        SpawnTrigger tempSpawn = new SpawnTrigger(spawnPos, spawnSize, "Spawn", pos, s, spawnCount++);

                        spawnTriggers.Add(tempSpawn);

                        string comboText = "Spawn " + spawnCount;

                        SpawnComboBox.Items.Add(comboText);
                        SpawnComboBox.SelectedIndex = spawnTriggers.Count() - 1;

                        SpawnXUpDown.Value = spawnPos.X;
                        SpawnYUpDown.Value = spawnPos.Y;
                        SpawnTrigXUpDown.Value = pos.X;
                        SpawnTrigYUpDown.Value = pos.Y;
                        SpawnTrigWidthUpDown.Value = s.Width;
                        SpawnTrigHeightUpDown.Value = s.Height;
                    }
                    else if (PlayerSpawnRadio.Checked && playerSpawnPoints.Count() < 4)
                    {
                        Size spawnSize = new Size(TM.GetTextureWidth(spawnPoint), TM.GetTextureHeight(spawnPoint));

                        pos.X -= (int)(spawnSize.Width / 2.0f);
                        pos.Y -= (int)(spawnSize.Height / 2.0f);

                        if (pos.X < 0)
                        {
                            pos.X = 0;
                        }

                        if (pos.Y < 0)
                        {
                            pos.Y = 0;
                        }

                        bool one = true;
                        bool two = true;
                        bool three = true;
                        bool four = true;

                        int id = 1;

                        for (int i = 0; i < playerSpawnPoints.Count(); i++)
                        {
                            if (playerSpawnPoints[i].id == 1)
                            {
                                one = false;
                            }

                            if (playerSpawnPoints[i].id == 2)
                            {
                                two = false;
                            }

                            if (playerSpawnPoints[i].id == 3)
                            {
                                three = false;
                            }

                            if (playerSpawnPoints[i].id == 4)
                            {
                                four = false;
                            }
                        }

                        if (one)
                        {
                            id = 1;
                        }
                        else if (two)
                        {
                            id = 2;
                        }
                        else if (three)
                        {
                            id = 3;
                        }
                        else if (four)
                        {
                            id = 4;
                        }

                        SpawnPoint tempSpawn = new SpawnPoint(pos, id);

                        playerSpawnPoints.Add(tempSpawn);
                        PlayerSpawnComboBox.Items.Add(tempSpawn);
                        PlayerSpawnComboBox.SelectedIndex = playerSpawnPoints.Count() - 1;

                        PlayerSpawnXUpDown.Value = pos.X;
                        PlayerSpawnYUpDown.Value = pos.Y;
                    }
                }
            }
        }

        private void AppContainer_Panel1_MouseDown(object sender, MouseEventArgs e)
        {
            int posX = AppContainer.Panel1.AutoScrollPosition.X;
            int posY = AppContainer.Panel1.AutoScrollPosition.Y;

            Point pos = new Point((int)((e.X - posX) / (scale)),
                                  (int)((e.Y - posY) / (scale)));

            if (SelectTriggerButton.Checked && isMouseDown == false)
            {
                isMouseDown = true;

                if (CollisionRadioButton.Checked)
                {
                    for (int i = 0; i < collisionTriggers.Count(); ++i)
                    {
                        if (pos.X > collisionTriggers[i].position.X && pos.X < (collisionTriggers[i].position.X + collisionTriggers[i].size.Width)
                        && pos.Y > collisionTriggers[i].position.Y && pos.Y < (collisionTriggers[i].position.Y + collisionTriggers[i].size.Height))
                        {
                            CollisionComboBox.SelectedIndex = i;
                            break;
                        }
                    }
                }
                else if (EventRadioButton.Checked)
                {
                    for (int i = 0; i < eventTriggers.Count(); ++i)
                    {
                        if (pos.X > eventTriggers[i].position.X && pos.X < (eventTriggers[i].position.X + eventTriggers[i].size.Width)
                        && pos.Y > eventTriggers[i].position.Y && pos.Y < (eventTriggers[i].position.Y + eventTriggers[i].size.Height))
                        {
                            EventComboBox.SelectedIndex = i;
                            break;
                        }
                    }
                }
                else if (SpawnRadioButton.Checked)
                {
                    for (int i = 0; i < spawnTriggers.Count(); ++i)
                    {
                        if (pos.X > spawnTriggers[i].position.X && pos.X < (spawnTriggers[i].position.X + spawnTriggers[i].size.Width)
                        && pos.Y > spawnTriggers[i].position.Y && pos.Y < (spawnTriggers[i].position.Y + spawnTriggers[i].size.Height))
                        {
                            SpawnComboBox.SelectedIndex = i;
                            isSpawnSelected = false;
                            break;
                        }
                        else if (pos.X > spawnTriggers[i].spawnPoint.X && pos.X < (spawnTriggers[i].spawnPoint.X + TM.GetTextureWidth(spawnPoint))
                                 && pos.Y > spawnTriggers[i].spawnPoint.Y && pos.Y < (spawnTriggers[i].spawnPoint.Y + TM.GetTextureWidth(spawnPoint)))
                        {
                            SpawnComboBox.SelectedIndex = i;
                            isSpawnSelected = true;
                            break;
                        }
                    }
                }
                else if (PlayerSpawnRadio.Checked)
                {
                    for (int i = 0; i < playerSpawnPoints.Count(); ++i)
                    {
                        if (pos.X > playerSpawnPoints[i].position.X && pos.X < (playerSpawnPoints[i].position.X + TM.GetTextureWidth(spawnPoint))
                        && pos.Y > playerSpawnPoints[i].position.Y && pos.Y < (playerSpawnPoints[i].position.Y + TM.GetTextureHeight(spawnPoint)))
                        {
                            PlayerSpawnComboBox.SelectedIndex = i;
                            break;
                        }
                    }
                }
            }
              
        }

        private void AppContainer_Panel1_MouseUp(object sender, MouseEventArgs e)
        {
            isMouseDown = false;
        }

        private void TileLayer2_Panel2_MouseClick(object sender, MouseEventArgs e)
        {
            int posY = TileLayer2.Panel2.AutoScrollPosition.Y;

            if ((e.Y - posY) < tileSets.Count() * (tilesetNotSelected.Height + 4))
            {
                if (selectedTileset != (e.Y - posY) / (tilesetNotSelected.Height + 4))
                {
                    selectedTileset = (e.Y - posY) / (tilesetNotSelected.Height + 4);
                    selectedSourceTile = new Point(-1, -1);

                    if (tileSets.Count > 0)
                    {
                        TilesetNameBox.Text = tileSets[selectedTileset].name;
                        TileWidthUpDown1.Value = tileSets[selectedTileset].tileSize.Width;
                        TileHeightUpDown1.Value = tileSets[selectedTileset].tileSize.Height;
                    }

                    TileLayer2.Panel2.Invalidate();
                    TileLayer.Panel1.Invalidate();
                }
            }
        }

        private void RenderWindowMouseWheelHandle(object sender, MouseEventArgs e)
        {
            if (e.Delta > 0)
            {
                scale += 0.15f;

                AppContainer.Panel1.Cursor = zoomIn;
                AppContainer.Panel1.AutoScrollMinSize = new Size((int)(tileWidth * mapWidth * scale), (int)(tileHeight * mapHeight * scale));
            }
            else
            {
                scale -= 0.15f;
                if (scale < 0.1f)
                {
                    scale = 0.1f;
                }

                AppContainer.Panel1.Cursor = zoomOut;
                AppContainer.Panel1.AutoScrollMinSize = new Size((int)(tileWidth * mapWidth * scale), (int)(tileHeight * mapHeight * scale));
            }
        }

        ///////////////////////
        /////// HOT KEYS //////
        ///////////////////////
        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            if (MapTab.SelectedIndex == 1)
            {
                switch (e.KeyCode)
                {
                    case Keys.Z:
                        {
                            PaintBrushButton.Checked = true;
                            PaintBucketButton.Checked = false;
                            EraserButton.Checked = false;
                            SelectTileButton.Checked = false;
                            AppContainer.Panel1.Cursor = paintBrush;
                        }
                        break;
                    case Keys.X:
                        {
                            PaintBrushButton.Checked = false;
                            PaintBucketButton.Checked = true;
                            EraserButton.Checked = false;
                            SelectTileButton.Checked = false;
                            AppContainer.Panel1.Cursor = paintBucket;
                        }
                        break;

                    case Keys.C:
                        {
                            PaintBrushButton.Checked = false;
                            PaintBucketButton.Checked = false;
                            EraserButton.Checked = true;
                            SelectTileButton.Checked = false;
                            AppContainer.Panel1.Cursor = eraser;
                        }
                        break;

                    case Keys.V:
                        {
                            PaintBrushButton.Checked = false;
                            PaintBucketButton.Checked = false;
                            EraserButton.Checked = false;
                            SelectTileButton.Checked = true;
                            AppContainer.Panel1.Cursor = select;
                        }
                        break;
                }

            }
            else if (MapTab.SelectedIndex == 2)
            {
                switch (e.KeyCode)
                {
                    case Keys.Z:
                        {
                            PlaceObjectButton.Checked = true;
                            SelectObjectButton.Checked = false;
                            MoveObjectButton.Checked = false;
                            AppContainer.Panel1.Cursor = add;
                        }
                        break;

                    case Keys.X:
                        {
                            PlaceObjectButton.Checked = false;
                            SelectObjectButton.Checked = false;
                            MoveObjectButton.Checked = true;
                            AppContainer.Panel1.Cursor = pan;
                        }
                        break;

                    case Keys.V:
                        {
                            PlaceObjectButton.Checked = false;
                            SelectObjectButton.Checked = true;
                            MoveObjectButton.Checked = false;
                            AppContainer.Panel1.Cursor = select;
                        }
                        break;

                    case Keys.Delete:
                        {
                            if (selectedProp != -1)
                            {
                                props.RemoveAt(selectedProp);
                                selectedProp = -1;
                            }
                            else if (selectedPowerup != -1)
                            {
                                powerups.RemoveAt(selectedPowerup);
                                selectedPowerup = -1;
                            }
                            else if (selectedEnemy != -1)
                            {
                                enemies.RemoveAt(selectedEnemy);
                                selectedEnemy = -1;
                            }
                        }
                        break;
                }
            }
            else if (MapTab.SelectedIndex == 3)
            {
                switch (e.KeyCode)
                {
                    case Keys.Delete:
                        {
                            if (lightSelected != -1)
                            {
                                lights.RemoveAt(lightSelected);                        
                                lightSelected = -1;
                            }
                        }
                        break;
                }
            }
            else if (MapTab.SelectedIndex == 4)
            {
                switch (e.KeyCode)
                {
                    case Keys.Delete:
                        {
                            if (collisionTriggers.Count() > 0 && CollisionRadioButton.Checked)
                            {
                                collisionTriggers.RemoveAt(CollisionComboBox.SelectedIndex);
                                CollisionComboBox.Items.RemoveAt(CollisionComboBox.SelectedIndex);

                                if (collisionTriggers.Count() > 0)
                                {
                                    CollisionComboBox.SelectedIndex = collisionTriggers.Count() - 1;
                                }
                            }
                            else if (eventTriggers.Count() > 0 && EventRadioButton.Checked)
                            {
                                eventTriggers.RemoveAt(EventComboBox.SelectedIndex);
                                EventComboBox.Items.RemoveAt(EventComboBox.SelectedIndex);

                                if (eventTriggers.Count() > 0)
                                {
                                    EventComboBox.SelectedIndex = eventTriggers.Count() - 1;
                                }
                            }
                            else if (playerSpawnPoints.Count() > 0 && PlayerSpawnRadio.Checked)
                            {
                                playerSpawnPoints.RemoveAt(PlayerSpawnComboBox.SelectedIndex);
                                PlayerSpawnComboBox.Items.RemoveAt(PlayerSpawnComboBox.SelectedIndex);

                                if (playerSpawnPoints.Count() > 0)
                                {
                                    PlayerSpawnComboBox.SelectedIndex = playerSpawnPoints.Count() - 1;
                                }
                            }
                            else if (spawnTriggers.Count() > 0 && SpawnRadioButton.Checked)
                            {
                                spawnTriggers.RemoveAt(SpawnComboBox.SelectedIndex);
                                SpawnComboBox.Items.RemoveAt(SpawnComboBox.SelectedIndex);

                                if (spawnTriggers.Count() > 0)
                                {
                                    SpawnComboBox.SelectedIndex = spawnTriggers.Count() - 1;
                                }
                            }

                        }
                        break;
                }
            }
        }

        ///////////////////////
        ////// RESIZING ///////
        ///////////////////////
        private void TileLayer1_Panel1_Resize(object sender, EventArgs e)
        {
            ImportTileset.Width = TileLayer2.Width - 10;
            RemoveTileset.Width = TileLayer2.Width - 10;
        }

        private void AppContainer_Panel1_Scroll(object sender, ScrollEventArgs e)
        {
            auxPos = new Point(-AppContainer.Panel1.AutoScrollPosition.X, -AppContainer.Panel1.AutoScrollPosition.Y);
        }

        private void ObjectGroupBox_Resize(object sender, EventArgs e)
        {
            PropRadioButton.Left = ObjectGroupBox.Left + 20;
            PowerUpRadioButton.Left = ObjectGroupBox.Right - PowerUpRadioButton.Width - 20;
            EnemyRadioButton.Left = (ObjectGroupBox.Width / 2) - (EnemyRadioButton.Width / 2);
        }

        private void ObjectViewSplit_Resize(object sender, EventArgs e)
        {
            ObjectViewSplit.SplitterDistance = ObjectViewSplit.Height - ObjectGroupBox.Height - ImportObjectButton.Height - RemoveObject.Height - 10;
        }

        private void ObjectInfoBox_Resize(object sender, EventArgs e)
        {
            ObjectNameTextBox.Width = ObjectInfoBox.Width - ObjectNameTextBox.Left - 10;
            EditObjectXUpDown.Width = ObjectInfoBox.Width - EditObjectXUpDown.Left - 10;
            EditObjectYUpDown.Width = ObjectInfoBox.Width - EditObjectYUpDown.Left - 10;
            ObjectHeightUpDown.Width = ObjectInfoBox.Width - ObjectHeightUpDown.Left - 10;
            ObjectWidthUpDown.Width = ObjectInfoBox.Width - ObjectWidthUpDown.Left - 10;
            ObjectTypeComboBox.Width = ObjectInfoBox.Width - ObjectTypeComboBox.Left - 10;
            EditObjectRotateUpDown.Width = ObjectInfoBox.Width - EditObjectRotateUpDown.Left - 10;
        }

        private void MapSplit_Panel1_Resize(object sender, EventArgs e)
        {
            MapWidthUpDown.Width = MapSplit.Panel1.Width - MapWidthUpDown.Left - 10;
            MapHeightUpDown.Width = MapSplit.Panel1.Width - MapHeightUpDown.Left - 10;
            TileWidthUpDown.Width = MapSplit.Panel1.Width - TileWidthUpDown.Left - 10;
            TileHeightUpDown.Width = MapSplit.Panel1.Width - TileHeightUpDown.Left - 10;
        }

        private void EditTilesetGroup_Resize(object sender, EventArgs e)
        {
            TileWidthUpDown1.Width = EditTilesetGroup.Width - TileWidthUpDown1.Left - 10;
            TileHeightUpDown1.Width = EditTilesetGroup.Width - TileHeightUpDown1.Left - 10;
            TilesetNameBox.Width = EditTilesetGroup.Width - TilesetNameBox.Left - 10;
        }

        private void TileLayer2_Resize(object sender, EventArgs e)
        {
            TileLayer2.SplitterDistance = EditTilesetGroup.Height + ImportTileset.Height + RemoveTileset.Height + TileToolStrip.Height + 20;
        }

        private void MapSplit_Resize(object sender, EventArgs e)
        {
            MapSplit.SplitterDistance = MapSizeGroup.Height + TileSizeGroup.Height + 10;
        }

        ///////////////////////
        ///// MENU STRIPS /////
        ///////////////////////
        private void toggleGridToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToggleGridStrip.Checked = !ToggleGridStrip.Checked;
            ToggleGridContext.Checked = !ToggleGridContext.Checked;
        }

        private void ToggleGridStrip_Click(object sender, EventArgs e)
        {
            ToggleGridStrip.Checked = !ToggleGridStrip.Checked;
            ToggleGridContext.Checked = !ToggleGridContext.Checked;
        }

        private void ToggleTileStrip_Click(object sender, EventArgs e)
        {
            ToggleTileContext.Checked = !ToggleTileContext.Checked;
            ToggleTileStrip.Checked = !ToggleTileStrip.Checked;
        }

        private void ToggleTileContext_Click(object sender, EventArgs e)
        {
            ToggleTileContext.Checked = !ToggleTileContext.Checked;
            ToggleTileStrip.Checked = !ToggleTileStrip.Checked;
        }

        private void ToggleCoordsContext_Click(object sender, EventArgs e)
        {
            ToggleCoordsContext.Checked = !ToggleCoordsContext.Checked;
            ToggleCoordsStrip.Checked = !ToggleCoordsStrip.Checked;
        }

        private void ToggleCoordsStrip_Click(object sender, EventArgs e)
        {
            ToggleCoordsContext.Checked = !ToggleCoordsContext.Checked;
            ToggleCoordsStrip.Checked = !ToggleCoordsStrip.Checked;
        }

        private void defaultZoomToolStripMenuItem_Click(object sender, EventArgs e)
        {
            scale = 1.0f;
            AppContainer.Panel1.AutoScrollMinSize = new Size((int)(tileWidth * mapWidth * scale), (int)(tileHeight * mapHeight * scale));
        }

        ///////////////////////
        ////// MAP LAYER //////
        ///////////////////////
        private void SetMapSizeButton_Click(object sender, EventArgs e)
        {
            Size newMapSize = new Size((int)MapWidthUpDown.Value, (int)MapHeightUpDown.Value);

            if (map.mapSize != newMapSize)
            {
                map.ResizeMap(newMapSize);

                mapWidth = (int)MapWidthUpDown.Value;
                mapHeight = (int)MapHeightUpDown.Value;

                MapResize();

                AppContainer.Panel1.AutoScrollMinSize = map.GetRect().Size;

                PreviewPanel.Invalidate();

                EditObjectXUpDown.Maximum = tileWidth * mapWidth;
                EditObjectYUpDown.Maximum = tileHeight * mapHeight;

                selectedEnemy = -1;
                selectedProp = -1;
                selectedPowerup = -1;
            }
        }

        private void TileSizeButton_Click(object sender, EventArgs e)
        {
            if (TileHeightUpDown.Value != tileHeight || TileWidthUpDown.Value != tileWidth)
            {
                map.tileSize.Width = (int)TileWidthUpDown.Value;
                map.tileSize.Height = (int)TileHeightUpDown.Value;
                tileWidth = (int)TileWidthUpDown.Value;
                tileHeight = (int)TileHeightUpDown.Value;

                MapResize();

                AppContainer.Panel1.AutoScrollMinSize = map.GetRect().Size;

                PreviewPanel.Invalidate();

                selectedEnemy = -1;
                selectedProp = -1;
                selectedPowerup = -1;
            }
        }

        private void MapResize()
        {
            for (int i = 0; i < props.Count(); ++i)
            {
                if (props[i].position.X + (props[i].size.Width/2) > map.GetRect().Width || props[i].position.Y + (props[i].size.Height/2) > map.GetRect().Height)
                {
                    props.RemoveAt(i);
                    --i;
                }
            }

            for (int i = 0; i < enemies.Count(); ++i)
            {
                if (enemies[i].position.X + (enemies[i].size.Width/2) > map.GetRect().Width || enemies[i].position.Y + (enemies[i].size.Height/2) > map.GetRect().Height)
                {
                    enemies.RemoveAt(i);
                    --i;
                }
            }

            for (int i = 0; i < powerups.Count(); ++i)
            {
                if (powerups[i].position.X + (powerups[i].size.Width/2) > map.GetRect().Width || powerups[i].position.Y + (powerups[i].size.Height/2) > map.GetRect().Height)
                {
                    powerups.RemoveAt(i);
                    --i;
                }
            }

            selectedPowerup = -1;
            selectedEnemy = -1;
            selectedProp = -1;
        }

        ///////////////////////
        ////// TILE LAYER /////
        ///////////////////////
        private void TileWidthUpDown1_ValueChanged(object sender, EventArgs e)
        {
            if (tileSets.Count > 0)
            {
                tileSets[selectedTileset].tileSize.Width = (int)TileWidthUpDown1.Value;
                TileLayer.Panel1.Invalidate();
                TileLayer2.Panel2.Invalidate();
            }
        }

        private void TileHeightUpDown1_ValueChanged(object sender, EventArgs e)
        {
            if (tileSets.Count > 0)
            {
                tileSets[selectedTileset].tileSize.Height = (int)TileHeightUpDown1.Value;
                TileLayer.Panel1.Invalidate();
                TileLayer2.Panel2.Invalidate();
            }
        }

        private void TilesetNameBox_TextChanged(object sender, EventArgs e)
        {
            if (tileSets.Count > 0)
            {
                tileSets[selectedTileset].name = TilesetNameBox.Text;
                TileLayer2.Panel2.Invalidate();
            }
        }

        private void MapTab_SelectedIndexChanged(object sender, EventArgs e)
        {
            selectedSourceTile = new Point(-1, -1);
            PaintBrushButton.Checked = false;
            PaintBucketButton.Checked = false;
            EraserButton.Checked = false;
            SelectTileButton.Checked = false;
            PlaceObjectButton.Checked = false;
            SelectObjectButton.Checked = false;
            AddTriggerButton.Checked = false;
            AppContainer.Panel1.Cursor = Cursors.Arrow;
            selectedObject = -1;
            SpawnRadioButton.Checked = false;
            CollisionRadioButton.Checked = false;
            EventRadioButton.Checked = false;
            lightToolSelected = false;
            SelectTriggerButton.Checked = false;
        }

        private void PaintBrushButton_Click(object sender, EventArgs e)
        {
            PaintBrushButton.Checked = true;
            PaintBucketButton.Checked = false;
            EraserButton.Checked = false;
            SelectTileButton.Checked = false;
        }

        private void PaintBucketButton_Click(object sender, EventArgs e)
        {
            PaintBrushButton.Checked = false;
            PaintBucketButton.Checked = true;
            EraserButton.Checked = false;
            SelectTileButton.Checked = false;
        }

        private void EraserButton_Click(object sender, EventArgs e)
        {
            PaintBrushButton.Checked = false;
            PaintBucketButton.Checked = false;
            EraserButton.Checked = true;
            SelectTileButton.Checked = false;
        }

        private void SelectTileButton_Click(object sender, EventArgs e)
        {
            PaintBrushButton.Checked = false;
            PaintBucketButton.Checked = false;
            EraserButton.Checked = false;
            SelectTileButton.Checked = true;
        }

        private void ImportTileset_Click(object sender, EventArgs e)
        {
            TileImport dlg = new TileImport(map.tileSize.Width, map.tileSize.Height);

            if (DialogResult.OK == dlg.ShowDialog(this))
            {
                if (dlg.fileName != null)
                {
                    TileSet imported = new TileSet(dlg.tilesetName, dlg.fileName, filePath + dlg.fileName, new Size(dlg.tilesetWidth / dlg.tileWidth, dlg.tilesetHeight / dlg.tileHeight), new Size(dlg.tileWidth, dlg.tileHeight), TM.LoadTexture(filePath + dlg.fileName, 0));
                    tileSets.Add(imported);
                    TileLayer.Panel1.Invalidate();
                    TileLayer2.Panel2.Invalidate();
                    selectedTileset = tileSets.Count() - 1;

                    TilesetNameBox.Text = dlg.tilesetName;
                    TileHeightUpDown1.Value = dlg.tileHeight;
                    TileWidthUpDown1.Value = dlg.tileWidth;
                }
            }
        }

        private void RemoveTileset_Click(object sender, EventArgs e)
        {
            String message = "Removing a tileset will remove any associated tiles.\n    Are you sure you want to remove the tileset?";

            RemoveDialog dlg = new RemoveDialog(message);

            if (DialogResult.OK == dlg.ShowDialog())
            {
                for (int x = 0; x < map.mapSize.Width; ++x)
                {
                    for (int y = 0; y < map.mapSize.Height; ++y)
                    {
                        if (map.mapMatrix[x, y].tileSetID == tileSets[selectedTileset].textureID)
                        {
                            map.mapMatrix[x, y].tile = new Point(-1, -1);
                        }

                        if (selectedTileset == 0)
                        {
                            if (map.tilesetIndex[x, y] == selectedTileset)
                            {
                                map.tilesetIndex[x, y] = -1;
                            }
                            else
                            {
                                --map.tilesetIndex[x, y];
                            }
                        }
                        else if (selectedTileset == tileSets.Count())
                        {
                            if (map.tilesetIndex[x, y] == selectedTileset)
                            {
                                map.tilesetIndex[x, y] = -1;
                            }
                        }
                        else
                        {
                            if (map.tilesetIndex[x, y] == selectedTileset)
                            {
                                map.tilesetIndex[x, y] = -1;
                            }
                            else if (map.tilesetIndex[x, y] > selectedTileset)
                            {
                                --map.tilesetIndex[x, y];
                            }
                        }
                    }
                }

                TM.ReleaseTexture(tileSets[selectedTileset].textureID);

                tileSets.RemoveAt(selectedTileset);

                if (tileSets.Count > 0)
                {
                    selectedTileset = 0;
                    selectedSourceTile = new Point(-1, -1);
                    TilesetNameBox.Text = tileSets[selectedTileset].name;
                    TileWidthUpDown1.Value = tileSets[selectedTileset].tileSize.Width;
                    TileHeightUpDown1.Value = tileSets[selectedTileset].tileSize.Height;
                }
                else
                {
                    TilesetNameBox.Text = "";
                }

                TileLayer.Panel1.Invalidate();
                TileLayer2.Panel2.Invalidate();
            }

        }

        private void PaintBucketFill(int posX, int posY)
        {
            if (map.tilesetIndex[posX,posY] != selectedTileset || map.mapMatrix[posX, posY].tile != selectedSourceTile)
            {
                List<Point> fillTile = new List<Point>();
                Point p = new Point(posX, posY);

                Point orignialTile = map.mapMatrix[posX, posY].tile;
                int originalIndex = map.tilesetIndex[posX, posY];

                fillTile.Add(p);

                while (fillTile.Count() > 0)
                {                
                    int x = fillTile[0].X;
                    int y = fillTile[0].Y;
                    fillTile.RemoveAt(0);

                    if (x - 1 >= 0 && orignialTile == map.mapMatrix[x - 1, y].tile
                        && originalIndex == map.tilesetIndex[x - 1, y])
                    {
                        Point left = new Point(x - 1, y);
                        if (fillTile.Contains(left) == false)
                        {
                            fillTile.Add(left);
                        }
                    }

                    if (x + 1 < map.mapSize.Width && orignialTile == map.mapMatrix[x + 1, y].tile
                        && originalIndex == map.tilesetIndex[x + 1, y])
                    {
                        Point right = new Point(x + 1, y);

                        if (fillTile.Contains(right) == false)
                        {
                            fillTile.Add(right);
                        }
                    }

                    if (y - 1 >= 0 && orignialTile == map.mapMatrix[x, y - 1].tile
                        && originalIndex == map.tilesetIndex[x, y - 1])
                    {                        
                        Point up = new Point(x, y - 1);
                        if (fillTile.Contains(up) == false)
                        {
                            fillTile.Add(up);
                        }
                    }

                    if (y + 1 < map.mapSize.Height && orignialTile == map.mapMatrix[x, y + 1].tile
                        && originalIndex == map.tilesetIndex[x, y + 1])
                    {
                        Point down = new Point(x, y + 1);
                        if (fillTile.Contains(down) == false)
                        {
                            fillTile.Add(down);
                        }
                    }

                    Tile t = new Tile(selectedSourceTile, tileSets[selectedTileset].textureID);
                    map.mapMatrix[x, y] = t;
                    map.tilesetIndex[x, y] = selectedTileset;
                                  
                }
            }
        }        

        ///////////////////////
        ///// OBJECT LAYER ////
        ///////////////////////
        private void PlaceObjectButton_Click(object sender, EventArgs e)
        {
            PlaceObjectButton.Checked = true;
            SelectObjectButton.Checked = false;
            MoveObjectButton.Checked = false;
        }

        private void MoveObjectButton_Click(object sender, EventArgs e)
        {
            MoveObjectButton.Checked = true;
            PlaceObjectButton.Checked = false;
            SelectObjectButton.Checked = false;
        }

        private void SelectObjectButton_Click(object sender, EventArgs e)
        {
            MoveObjectButton.Checked = false;
            PlaceObjectButton.Checked = false;
            SelectObjectButton.Checked = true;
        }

        private void RotateButton_Click(object sender, EventArgs e)
        {
            PlaceObjectButton.Checked = false;
            SelectObjectButton.Checked = false;
        }

        private void RemoveObjectButton_Click(object sender, EventArgs e)
        {
            PlaceObjectButton.Checked = false;
            SelectObjectButton.Checked = false;
        }

        private void ObjectSelectButton_Click(object sender, EventArgs e)
        {
            PlaceObjectButton.Checked = false;
            SelectObjectButton.Checked = true;
        }

        private void ImportObjectButton_Click(object sender, EventArgs e)
        {
            if (PropRadioButton.Checked)
            {
                ObjectImport dlg = new ObjectImport();

                if (DialogResult.OK == dlg.ShowDialog(this))
                {
                    if (dlg.fileName != null)
                    {
                        Object imported = new Object(dlg.objectName, dlg.fileName, filePath + dlg.fileName, new Size(dlg.objectWidth, dlg.objectHeight), new Point(0, 0), 0, 0, TM.LoadTexture(filePath + dlg.fileName, 0));
                        availableObjects.Add(imported);
                        RemoveObject.Enabled = true;
                    }
                }
            }
            if (EnemyRadioButton.Checked)
            {
                EnemyImport dlg = new EnemyImport();

                if (DialogResult.OK == dlg.ShowDialog(this))
                {
                    if (dlg.fileName != null)
                    {
                        bool alreadyExist = false;

                        for (int i = 0; i < availableObjects.Count(); ++i)
                        {
                            if (availableObjects[i].name == dlg.objectName)
                            {
                                Bitmap temp = new Bitmap(dlg.fileName);
                                availableObjects[i].bitmap = temp;
                                availableObjects[i].size = new Size(dlg.objectWidth, dlg.objectHeight);
                                availableObjects[i].filePath = dlg.fileName;

                                if (selectedObject == i)
                                {
                                    ObjectWidthUpDown.Value = dlg.objectWidth;
                                    ObjectHeightUpDown.Value = dlg.objectHeight;
                                }

                                TM.ReleaseTexture(availableObjects[i].textureID);
                                availableObjects[i].textureID = TM.LoadTexture(dlg.fileName, 0);

                                for (int j = 0; j < enemies.Count(); ++j)
                                {
                                    if (enemies[i].name == dlg.objectName)
                                    {
                                        enemies[i].bitmap = temp;
                                        enemies[i].textureID = availableObjects[i].textureID;
                                        enemies[i].size = availableObjects[i].size;
                                        enemies[i].filePath = availableObjects[i].filePath;
                                    }
                                }
                                alreadyExist = true;
                                break;   
                            }
                        }

                        if (alreadyExist == false)
                        {
                            Object imported = new Object(dlg.objectName, dlg.fileName, filePath + dlg.fileName, new Size(dlg.objectWidth, dlg.objectHeight), new Point(0, 0), 0, 1, TM.LoadTexture(filePath + dlg.fileName, 0));
                            availableObjects.Add(imported);
                        }
                        RemoveObject.Enabled = true;              
                    }
                }
            }
            if (PowerUpRadioButton.Checked)
            {
                PowerupImport dlg = new PowerupImport();

                if (DialogResult.OK == dlg.ShowDialog(this))
                {
                    if (dlg.fileName != null)
                    {
                        bool alreadyExist = false;

                        for (int i = 0; i < availableObjects.Count(); ++i)
                        {
                            if (availableObjects[i].name == dlg.objectName)
                            {
                                Bitmap temp = new Bitmap(dlg.fileName);
                                availableObjects[i].bitmap = temp;
                                availableObjects[i].size = new Size(dlg.objectWidth, dlg.objectHeight);
                                availableObjects[i].filePath = dlg.fileName;

                                if (selectedObject == i)
                                {
                                    ObjectWidthUpDown.Value = dlg.objectWidth;
                                    ObjectHeightUpDown.Value = dlg.objectHeight;
                                }

                                TM.ReleaseTexture(availableObjects[i].textureID);
                                availableObjects[i].textureID = TM.LoadTexture(dlg.fileName, 0);

                                for (int j = 0; j < powerups.Count(); ++j)
                                {
                                    if (powerups[i].name == dlg.objectName)
                                    {
                                        powerups[i].bitmap = temp;
                                        powerups[i].textureID = availableObjects[i].textureID;
                                        powerups[i].size = availableObjects[i].size;
                                        powerups[i].filePath = availableObjects[i].filePath;
                                    }
                                }
                                alreadyExist = true;
                                break;
                            }
                        }

                        if (alreadyExist == false)
                        {
                            Object imported = new Object(dlg.objectName, dlg.fileName, filePath + dlg.fileName, new Size(dlg.objectWidth, dlg.objectHeight), new Point(0, 0), 0, 2, TM.LoadTexture(filePath + dlg.fileName, 0));
                            availableObjects.Add(imported);
                        }
                        RemoveObject.Enabled = true;
                    }
                }
            }

            selectedObject = availableObjects.Count() - 1;
            PlaceObjectButton.Checked = true;

            if (selectedObject != -1)
            {
                ObjectNameTextBox.Text = availableObjects[selectedObject].name;
                ObjectWidthUpDown.Value = availableObjects[selectedObject].size.Width;
                ObjectHeightUpDown.Value = availableObjects[selectedObject].size.Height;
                ObjectTypeComboBox.SelectedIndex = availableObjects[selectedObject].objType;
            }

            ObjectViewAutoScrollSize();

            ObjectViewSplit.Panel1.Invalidate();
        }

        private void ObjectViewSplit_Panel1_Paint(object sender, PaintEventArgs e)
        {          
            int xOffset = 0;

            int posX = ObjectViewSplit.Panel1.AutoScrollPosition.X;

            Pen pen = new Pen(Brushes.Red, 2);

            for (int i = 0; i < availableObjects.Count(); ++i)
            {
                if (PropRadioButton.Checked && availableObjects[i].objType == 0)
                {
                    Rectangle source = new Rectangle(0, 0, availableObjects[i].bitmap.Width, availableObjects[i].bitmap.Height);

                    Rectangle dest = new Rectangle(xOffset + posX, 0, (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height)),
                                                   ((int)(availableObjects[i].size.Height * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height))));

                    e.Graphics.DrawImage(availableObjects[i].bitmap, dest, source, GraphicsUnit.Pixel);

                    if (selectedObject == i)
                    {                  
                        e.Graphics.DrawRectangle(pen, xOffset + posX, 0, (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 22) / (float)availableObjects[i].size.Height)),
                                                       ((int)(availableObjects[i].size.Height * ((ObjectViewSplit.Panel1.Height - 21) / (float)availableObjects[i].size.Height))));
                    }

                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));
                }
                else if (EnemyRadioButton.Checked && availableObjects[i].objType == 1)
                {
                    Rectangle source = new Rectangle(0, 0, availableObjects[i].bitmap.Width, availableObjects[i].bitmap.Height);

                    Rectangle dest = new Rectangle(xOffset + posX, 0, (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height)),
                                                   ((int)(availableObjects[i].size.Height * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height))));

                    e.Graphics.DrawImage(availableObjects[i].bitmap, dest, source, GraphicsUnit.Pixel);

                    if (selectedObject == i)
                    {
                        e.Graphics.DrawRectangle(pen, xOffset + posX, 0, (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 22) / (float)availableObjects[i].size.Height)),
                                                       ((int)(availableObjects[i].size.Height * ((ObjectViewSplit.Panel1.Height - 21) / (float)availableObjects[i].size.Height))));
                    }

                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));                    
                }
                else if (PowerUpRadioButton.Checked && availableObjects[i].objType == 2)
                {
                    Rectangle source = new Rectangle(0, 0, availableObjects[i].bitmap.Width, availableObjects[i].bitmap.Height);

                    Rectangle dest = new Rectangle(xOffset + posX, 0, (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height)),
                                                   ((int)(availableObjects[i].size.Height * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height))));

                    e.Graphics.DrawImage(availableObjects[i].bitmap, dest, source, GraphicsUnit.Pixel);

                    if (selectedObject == i)
                    {
                        e.Graphics.DrawRectangle(pen, xOffset + posX, 0, (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 22) / (float)availableObjects[i].size.Height)),
                                                       ((int)(availableObjects[i].size.Height * ((ObjectViewSplit.Panel1.Height - 21) / (float)availableObjects[i].size.Height))));
                    }

                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));
                }
            }                     
        }

        private void PropRadioButton_CheckedChanged(object sender, EventArgs e)
        {            
            ObjectViewAutoScrollSize();

            if (PropRadioButton.Checked)
            {
                ObjectNameTextBox.Enabled = true;
            }
            else
            {
                ObjectNameTextBox.Enabled = false;
            }

            ObjectViewSplit.Panel1.Invalidate();
        }

        private void EnemyRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            ObjectViewAutoScrollSize();

            if (PropRadioButton.Checked)
            {
                ObjectNameTextBox.Enabled = true;
            }
            else
            {
                ObjectNameTextBox.Enabled = false;
            }

            ObjectViewSplit.Panel1.Invalidate();
        }

        private void PowerUpRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            ObjectViewAutoScrollSize();

            if (PropRadioButton.Checked)
            {
                ObjectNameTextBox.Enabled = true;
            }
            else
            {
                ObjectNameTextBox.Enabled = false;
            }

            ObjectViewSplit.Panel1.Invalidate();
        }

        private void ObjectViewAutoScrollSize()
        {       
            int xOffset = 0;

            for (int i = 0; i < availableObjects.Count(); ++i)
            {
                if (PropRadioButton.Checked && availableObjects[i].objType == 0)
                {
                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));
                }
                else if (EnemyRadioButton.Checked && availableObjects[i].objType == 1)
                {
                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));
                }
                else if (PowerUpRadioButton.Checked && availableObjects[i].objType == 2)
                {
                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));
                }
            }

            ObjectViewSplit.Panel1.AutoScrollMinSize = new Size(xOffset, 0);
        }

        private void ObjectViewSplit_Panel1_MouseClick(object sender, MouseEventArgs e)
        {
            int xOffset = 0;
            int newSelection = 0;

            int posX = e.X - ObjectViewSplit.Panel1.AutoScrollPosition.X;

            for (int i = 0; i < availableObjects.Count(); ++i)
            {
                if (PropRadioButton.Checked && availableObjects[i].objType == 0)
                {
                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));
                    if(posX < xOffset)
                    {
                        break;
                    }
                }
                else if (EnemyRadioButton.Checked && availableObjects[i].objType == 1)
                {
                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));
                    if(posX < xOffset)
                    {
                        break;
                    }
                }
                else if (PowerUpRadioButton.Checked && availableObjects[i].objType == 2)
                {
                    xOffset += (int)(availableObjects[i].size.Width * ((ObjectViewSplit.Panel1.Height - 20) / (float)availableObjects[i].size.Height));
                    if(posX < xOffset)
                    {
                        break;
                    }
                }

                ++newSelection;
            }

            if (selectedObject != newSelection && newSelection < availableObjects.Count())
            {
                selectedObject = newSelection;
                ObjectViewSplit.Panel1.Invalidate();

                ObjectNameTextBox.Text = availableObjects[selectedObject].name;
                ObjectWidthUpDown.Value = availableObjects[selectedObject].size.Width;
                ObjectHeightUpDown.Value = availableObjects[selectedObject].size.Height;
                ObjectTypeComboBox.SelectedIndex = availableObjects[selectedObject].objType;

                PlaceObjectButton.Checked = true;
                RemoveObject.Enabled = true;
            }

        }

        private void ObjectWidthUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (selectedObject != -1)
            {
                availableObjects[selectedObject].size.Width = (int)ObjectWidthUpDown.Value;
            }
        }

        private void ObjectHeightUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (selectedObject != -1)
            {
                availableObjects[selectedObject].size.Height = (int)ObjectHeightUpDown.Value;
            }
        }

        private void RemoveObject_Click(object sender, EventArgs e)
        {
            String message = "   Removing a object will remove any associated \n                                  objects.\n    Are you sure you want to remove the object?";

            RemoveDialog dlg = new RemoveDialog(message);

            if (DialogResult.OK == dlg.ShowDialog())
            {
                int count = 0;

                for (int i = 0; i < availableObjects.Count(); ++i)
                {
                    if (availableObjects[i].textureID == availableObjects[selectedObject].textureID)
                    {
                        ++count;
                    }
                }
                
                if( count == 1)
                {
                    TM.ReleaseTexture(availableObjects[selectedObject].textureID);
                }

                if (availableObjects[selectedObject].objType == 0)
                {
                    for (int i = 0; i < props.Count(); ++i)
                    {
                        if (props[i].textureID == availableObjects[selectedObject].textureID)
                        {
                            props.RemoveAt(i);
                            --i;
                        }
                    }
                }
                else if (availableObjects[selectedObject].objType == 1)
                {
                    for (int i = 0; i < enemies.Count(); ++i)
                    {
                        if (enemies[i].textureID == availableObjects[selectedObject].textureID)
                        {
                            enemies.RemoveAt(i);
                            --i;
                        }
                    }
                }
                else if (availableObjects[selectedObject].objType == 2)
                {
                    for (int i = 0; i < powerups.Count(); ++i)
                    {
                        if (powerups[i].textureID == availableObjects[selectedObject].textureID)
                        {
                            powerups.RemoveAt(i);
                            --i;
                        }
                    }
                }

                availableObjects.RemoveAt(selectedObject);

                selectedObject = -1;

                ObjectNameTextBox.Text = "";
                ObjectWidthUpDown.Value = 1;
                ObjectHeightUpDown.Value = 1;

                RemoveObject.Enabled = false;
                ObjectViewSplit.Panel1.Invalidate();
            }
        }

        private void EditObjectXUpDown_ValueChanged(object sender, EventArgs e)
        {            
            if (selectedProp != -1)
            {
                EditObjectXUpDown.Maximum = (tileWidth * mapWidth) - props[selectedProp].size.Width;
                props[selectedProp].position.X = (int)EditObjectXUpDown.Value;
            }
            else if (selectedEnemy != -1)
            {
                EditObjectXUpDown.Maximum = (tileWidth * mapWidth) - enemies[selectedEnemy].size.Width;
                enemies[selectedEnemy].position.X = (int)EditObjectXUpDown.Value;
            }
            else if (selectedPowerup != -1)
            {
                EditObjectXUpDown.Maximum = (tileWidth * mapWidth) - powerups[selectedPowerup].size.Width;
                powerups[selectedPowerup].position.X = (int)EditObjectXUpDown.Value;
            }
        }

        private void EditObjectYUpDown_ValueChanged(object sender, EventArgs e)
        {            
            if (selectedProp != -1)
            {
                EditObjectYUpDown.Maximum = (tileHeight * mapHeight) - props[selectedProp].size.Width;
                props[selectedProp].position.Y = (int)EditObjectYUpDown.Value;
            }
            else if (selectedEnemy != -1)
            {
                EditObjectYUpDown.Maximum = (tileHeight * mapHeight) - enemies[selectedEnemy].size.Width;
                enemies[selectedEnemy].position.Y = (int)EditObjectYUpDown.Value;
            }
            else if (selectedPowerup != -1)
            {
                EditObjectYUpDown.Maximum = (tileHeight * mapHeight) - powerups[selectedPowerup].size.Width;
                powerups[selectedPowerup].position.Y = (int)EditObjectYUpDown.Value;
            }
        }

        private void EditObjectRotateUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (selectedProp != -1)
            {
                props[selectedProp].rotation = (int)EditObjectRotateUpDown.Value;
            }
            else if (selectedEnemy != -1)
            {
                enemies[selectedEnemy].rotation = (int)EditObjectRotateUpDown.Value;
            }
            else if (selectedPowerup != -1)
            {
                powerups[selectedPowerup].rotation = (int)EditObjectRotateUpDown.Value;
            }
        }

        private float DegreeToRadian(int angle)
        {
            return (float)(Math.PI * angle / 180.0f);
        }

        private void tileObjectLayerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToggleObjectsContextMenu.Checked = !ToggleObjectsContextMenu.Checked;
            tileObjectLayerToolStripMenuItem.Checked = !tileObjectLayerToolStripMenuItem.Checked;
        }

        private void ToggleObjectsContextMenu_Click(object sender, EventArgs e)
        {
            ToggleObjectsContextMenu.Checked = !ToggleObjectsContextMenu.Checked;
            tileObjectLayerToolStripMenuItem.Checked = !tileObjectLayerToolStripMenuItem.Checked;
        }

        private void ObjectNameTextBox_TextChanged(object sender, EventArgs e)
        {
            if (selectedObject != -1)
            {
                availableObjects[selectedObject].name = ObjectNameTextBox.Text;
            }
        }

        ///////////////////////
        ////// SAVE/LOAD //////
        ///////////////////////
        public void CheckFilePath()
        {
            try
            {
                System.IO.StreamReader reader = new System.IO.StreamReader(Application.StartupPath + "\\data\\resource_path.txt");

                filePath = reader.ReadLine();

                reader.Close();
            }
            catch
            {
                FolderBrowserDialog dlg = new FolderBrowserDialog();
                dlg.Description = "Find the resources folder";

                if (DialogResult.OK == dlg.ShowDialog(this))
                {
                    filePath = dlg.SelectedPath + "\\";

                    System.IO.StreamWriter writer = new System.IO.StreamWriter(Application.StartupPath + "\\data\\resource_path.txt");
                    writer.WriteLine(filePath);

                    writer.Close();
                }
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "XmlFiles|*.xml";
            dlg.FilterIndex = 1;

            dlg.DefaultExt = "xml";

            if (DialogResult.OK == dlg.ShowDialog())
            {
                XElement root = new XElement("Map");

                XElement tileLayer = new XElement("TileLayer");
                root.Add(tileLayer);

                XElement mapSize = new XElement("MapSize");
                tileLayer.Add(mapSize);

                XElement mWidth = new XElement("MapWidth", mapWidth.ToString());
                mapSize.Add(mWidth);

                XElement mHeight = new XElement("MapHeight", mapHeight.ToString());
                mapSize.Add(mHeight);

                XElement mtWidth = new XElement("MapTileWidth", tileWidth.ToString());
                mapSize.Add(mtWidth);

                XElement mtHeight = new XElement("MapTileHeight", tileHeight.ToString());
                mapSize.Add(mtHeight);

                XElement tilesets = new XElement("Tilesets");
                tileLayer.Add(tilesets);

                for ( int i = 0; i < tileSets.Count(); ++i)
                {
                    XElement tileset = new XElement("Tileset");
                    tilesets.Add(tileset);

                    XElement name = new XElement("Name", tileSets[i].name);
                    tileset.Add(name);

                    XElement fileName = new XElement("FileName", tileSets[i].fileName);
                    tileset.Add(fileName);

                    XElement tWidth = new XElement("TileWidth", tileSets[i].tileSize.Width);
                    tileset.Add(tWidth);

                    XElement tHeight = new XElement("TileHeight", tileSets[i].tileSize.Height);
                    tileset.Add(tHeight);

                    XElement setWidth = new XElement("TilesetWidth", tileSets[i].size.Width);
                    tileset.Add(setWidth);

                    XElement setHeight = new XElement("TilesetHeight", tileSets[i].size.Height);
                    tileset.Add(setHeight);
                }

                XElement coord = new XElement("Coordinates");
                tileLayer.Add(coord);

                for (int x = 0; x < map.mapSize.Width; ++x)
                {
                    for (int y = 0; y < map.mapSize.Height; ++y)
                    {
                        XElement xy = new XElement("XY");
                        coord.Add(xy);

                        XElement xCoord = new XElement("xCoordinate", map.mapMatrix[x, y].tile.X.ToString());
                        xy.Add(xCoord);

                        XElement yCoord = new XElement("yCoordinate", map.mapMatrix[x, y].tile.Y.ToString());
                        xy.Add(yCoord);

                        XElement tilesetID = new XElement("TilesetID", map.tilesetIndex[x, y].ToString());
                        xy.Add(tilesetID);
                    }
                }

                XElement objectLayer = new XElement("ObjectLayer");
                root.Add(objectLayer);

                XElement objects = new XElement("AvaialbleObjects");
                objectLayer.Add(objects);

                for (int i = 0; i < availableObjects.Count(); ++i)
                {
                    XElement obj = new XElement("Object");
                    objects.Add(obj);

                    XElement objName = new XElement("Name", availableObjects[i].name);
                    obj.Add(objName);

                    XElement objFileName = new XElement("FileName", availableObjects[i].fileName);
                    obj.Add(objFileName);

                    XElement objWidth = new XElement("Width", availableObjects[i].size.Width.ToString());
                    obj.Add(objWidth);

                    XElement objHeight = new XElement("Height", availableObjects[i].size.Height.ToString());
                    obj.Add(objHeight);

                    XElement objType = new XElement("Type", availableObjects[i].objType.ToString());
                    obj.Add(objType);
                }

                XElement propObjs = new XElement("Props");
                objectLayer.Add(propObjs);

                for (int i = 0; i < props.Count(); ++i)
                {
                    XElement prop = new XElement("Prop");
                    propObjs.Add(prop);

                    XElement objName = new XElement("Name", props[i].name);
                    prop.Add(objName);

                    XElement objFileName = new XElement("FileName", props[i].fileName);
                    prop.Add(objFileName);

                    XElement objWidth = new XElement("Width", props[i].size.Width.ToString());
                    prop.Add(objWidth);

                    XElement objHeight = new XElement("Height", props[i].size.Height.ToString());
                    prop.Add(objHeight);

                    XElement objType = new XElement("Type", props[i].objType.ToString());
                    prop.Add(objType);

                    XElement posX = new XElement("PositionX", props[i].position.X.ToString());
                    prop.Add(posX);

                    XElement posY = new XElement("PositionY", props[i].position.Y.ToString());
                    prop.Add(posY);

                    XElement rotation = new XElement("Rotation", props[i].rotation.ToString());
                    prop.Add(rotation);
                }

                XElement enemyObjs = new XElement("Enemies");
                objectLayer.Add(enemyObjs);

                for (int i = 0; i < enemies.Count(); ++i)
                {
                    XElement enemy = new XElement("Enemy");
                    enemyObjs.Add(enemy);

                    XElement objName = new XElement("Name", enemies[i].name);
                    enemy.Add(objName);

                    XElement objFileName = new XElement("FileName", enemies[i].fileName);
                    enemy.Add(objFileName);

                    XElement objWidth = new XElement("Width", enemies[i].size.Width.ToString());
                    enemy.Add(objWidth);

                    XElement objHeight = new XElement("Height", enemies[i].size.Height.ToString());
                    enemy.Add(objHeight);

                    XElement objType = new XElement("Type", enemies[i].objType.ToString());
                    enemy.Add(objType);

                    XElement posX = new XElement("PositionX", enemies[i].position.X.ToString());
                    enemy.Add(posX);

                    XElement posY = new XElement("PositionY", enemies[i].position.Y.ToString());
                    enemy.Add(posY);

                    XElement rotation = new XElement("Rotation", enemies[i].rotation.ToString());
                    enemy.Add(rotation);
                }

                XElement powerupObjs = new XElement("Powerups");
                objectLayer.Add(powerupObjs);

                for (int i = 0; i < powerups.Count(); ++i)
                {
                    XElement powerup = new XElement("Powerup");
                    powerupObjs.Add(powerup);

                    XElement objName = new XElement("Name", powerups[i].name);
                    powerup.Add(objName);

                    XElement objFileName = new XElement("FileName", powerups[i].fileName);
                    powerup.Add(objFileName);

                    XElement objWidth = new XElement("Width", powerups[i].size.Width.ToString());
                    powerup.Add(objWidth);

                    XElement objHeight = new XElement("Height", powerups[i].size.Height.ToString());
                    powerup.Add(objHeight);

                    XElement objType = new XElement("Type", powerups[i].objType.ToString());
                    powerup.Add(objType);

                    XElement posX = new XElement("PositionX", powerups[i].position.X.ToString());
                    powerup.Add(posX);

                    XElement posY = new XElement("PositionY", powerups[i].position.Y.ToString());
                    powerup.Add(posY);

                    XElement rotation = new XElement("Rotation", powerups[i].rotation.ToString());
                    powerup.Add(rotation);
                }

                XElement triggerLayer = new XElement("TriggerLayer");
                root.Add(triggerLayer);

                XElement eventTrig = new XElement("EventTriggers");
                triggerLayer.Add(eventTrig);

                for (int i = 0; i < eventTriggers.Count(); ++i)
                {
                    XElement eve = new XElement("Event");
                    eventTrig.Add(eve);

                    XElement name = new XElement("EventName", eventTriggers[i].eventName);
                    eve.Add(name);

                    XElement posX = new XElement("PositionX", eventTriggers[i].position.X.ToString());
                    eve.Add(posX);

                    XElement posY = new XElement("PositionY", eventTriggers[i].position.Y.ToString());
                    eve.Add(posY);

                    XElement width = new XElement("Width", eventTriggers[i].size.Width.ToString());
                    eve.Add(width);

                    XElement height = new XElement("Height", eventTriggers[i].size.Height.ToString());
                    eve.Add(height);

                    XElement repeat = new XElement("Repeatable", eventTriggers[i].isRepeatable.ToString());
                    eve.Add(repeat);

                    XElement id = new XElement("ID", eventTriggers[i].id.ToString());
                    eve.Add(id);
                }

                XElement collsionTrig = new XElement("CollisionTriggers");
                triggerLayer.Add(collsionTrig);

                for (int i = 0; i < collisionTriggers.Count(); ++i)
                {
                    XElement col = new XElement("Collision");
                    collsionTrig.Add(col);

                    XElement name = new XElement("EventName", collisionTriggers[i].eventName);
                    col.Add(name);

                    XElement posX = new XElement("PositionX", collisionTriggers[i].position.X.ToString());
                    col.Add(posX);

                    XElement posY = new XElement("PositionY", collisionTriggers[i].position.Y.ToString());
                    col.Add(posY);

                    XElement width = new XElement("Width", collisionTriggers[i].size.Width.ToString());
                    col.Add(width);

                    XElement height = new XElement("Height", collisionTriggers[i].size.Height.ToString());
                    col.Add(height);

                    XElement id = new XElement("ID", collisionTriggers[i].id.ToString());
                    col.Add(id);
                }

                XElement spawnTrig = new XElement("SpawnTriggers");
                triggerLayer.Add(spawnTrig);

                for (int i = 0; i < spawnTriggers.Count(); ++i)
                {
                    XElement spn = new XElement("Spawn");
                    spawnTrig.Add(spn);

                    XElement name = new XElement("EventName", "Spawn" + spawnTriggers[i].id.ToString());
                    spn.Add(name);

                    XElement posX = new XElement("PositionX", spawnTriggers[i].position.X.ToString());
                    spn.Add(posX);

                    XElement posY = new XElement("PositionY", spawnTriggers[i].position.Y.ToString());
                    spn.Add(posY);

                    XElement width = new XElement("Width", spawnTriggers[i].size.Width.ToString());
                    spn.Add(width);

                    XElement height = new XElement("Height", spawnTriggers[i].size.Height.ToString());
                    spn.Add(height);

                    XElement spawnPosX = new XElement("SpawnPointX", spawnTriggers[i].spawnPoint.X.ToString());
                    spn.Add(spawnPosX);

                    XElement spawnPosY = new XElement("SpawnPointY", spawnTriggers[i].spawnPoint.Y.ToString());
                    spn.Add(spawnPosY);

                    XElement id = new XElement("ID", spawnTriggers[i].id.ToString());
                    spn.Add(id);
                }

                XElement playerSpawn = new XElement("PlayerSpawns");
                triggerLayer.Add(playerSpawn);

                for (int i = 0; i < playerSpawnPoints.Count(); ++i)
                {
                    XElement spn = new XElement("Spawn");
                    playerSpawn.Add(spn);

                    XElement player = new XElement("PlayerNum", playerSpawnPoints[i].id.ToString());
                    spn.Add(player);

                    XElement posX = new XElement("PositionX", playerSpawnPoints[i].position.X.ToString());
                    spn.Add(posX);

                    XElement posY = new XElement("PositionY", playerSpawnPoints[i].position.Y.ToString());
                    spn.Add(posY);
                }

                XElement lightLayer = new XElement("LightLayer");
                root.Add(lightLayer);

                XElement lightList = new XElement("Lights");
                lightLayer.Add(lightList);

                for (int i = 0; i < lights.Count(); ++i)
                {
                    XElement light = new XElement("Light");
                    light.Add(light);

                    XElement colorR = new XElement("Red", Color.FromArgb(lights[i].color).R);
                    light.Add(colorR);
                    XElement colorG = new XElement("Green", Color.FromArgb(lights[i].color).G);
                    light.Add(colorG);
                    XElement colorB = new XElement("Blue", Color.FromArgb(lights[i].color).B);
                    light.Add(colorB);

                    XElement posX = new XElement("PositionX", lights[i].positionX.ToString());
                    light.Add(posX);

                    XElement posY = new XElement("PositionY", lights[i].positionY.ToString());
                    light.Add(posY);

                    XElement intensity = new XElement("Intensity", lights[i].intensity.ToString());
                    light.Add(intensity);

                    XElement radius = new XElement("Radius", lights[i].radius.ToString());
                    light.Add(radius);

                    lightList.Add(light);
                }

                XElement ambient = new XElement("AmbientLight");
                lightLayer.Add(ambient);

                XElement r = new XElement("R", ambientColor[0].ToString());
                ambient.Add(r);

                XElement g = new XElement("G", ambientColor[1].ToString());
                ambient.Add(g);

                XElement b = new XElement("B", ambientColor[2].ToString());
                ambient.Add(b);

                XElement intense = new XElement("Intensity", ambientIntensity.ToString());
                ambient.Add(intense);

                root.Save(dlg.FileName);
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Xml Files|*.xml";
            dlg.FilterIndex = 1;

            if (DialogResult.OK == dlg.ShowDialog())
            {
                if (dlg.FileName !=  filePath + "Data\\Levels\\" + dlg.SafeFileName)
                {
                    MessageBox.Show(Form1.ActiveForm, "Unable to load level. Please load levels from\nthe proper resource folder:\n" + filePath + "\nData\\Levels\\");
                    return;
                }

                ambientColor[0] = 1.0f;
                ambientColor[1] = 1.0f;
                ambientColor[2] = 1.0f;
                ambientIntensity = 1.0f;

                tileSets.Clear();
                availableObjects.Clear();
                props.Clear();
                powerups.Clear();
                enemies.Clear();
                eventTriggers.Clear();
                spawnTriggers.Clear();                
                collisionTriggers.Clear();
                playerSpawnPoints.Clear();
                EventComboBox.Items.Clear();
                SpawnComboBox.Items.Clear();
                CollisionComboBox.Items.Clear();
                PlayerSpawnComboBox.Items.Clear();
                lights.Clear();

                selectedObject = -1;
                selectedProp = -1;
                selectedPowerup = -1;
                selectedEnemy = -1;
                selectedSourceTile = new Point(-1, -1);
                lightSelected = -1;

                XElement root = XElement.Load(dlg.FileName);

                XElement tileLayer = root.Element("TileLayer");
                XElement mapSize = tileLayer.Element("MapSize");

                XElement mWidth = mapSize.Element("MapWidth");
                XElement mHeight = mapSize.Element("MapHeight");

                if (mWidth != null && mHeight != null)
                {
                    Size s = new Size(Convert.ToInt32(mWidth.Value), Convert.ToInt32(mHeight.Value));

                    mapWidth = s.Width;
                    mapHeight = s.Height;

                    MapWidthUpDown.Value = mapWidth;
                    MapHeightUpDown.Value = mapHeight;

                    map.ResizeMap(s);
                }

                XElement mapTileWidth = mapSize.Element("MapTileWidth");
                XElement mapTileHeight = mapSize.Element("MapTileHeight");

                if (mapTileWidth != null && mapTileHeight != null)
                {
                    Size s = new Size(Convert.ToInt32(mapTileWidth.Value), Convert.ToInt32(mapTileHeight.Value));

                    tileWidth = s.Width;
                    tileHeight = s.Height;

                    TileWidthUpDown.Value= tileWidth;
                    TileHeightUpDown.Value = tileHeight;                    

                    map.tileSize = s;      
                }

                MapResize();

                EditObjectXUpDown.Maximum = mapWidth * tileWidth;
                EditObjectYUpDown.Maximum = mapHeight * tileHeight;

                AppContainer.Panel1.AutoScrollMinSize = new Size(mapWidth * tileWidth, mapHeight * tileHeight);

                XElement tilesets = tileLayer.Element("Tilesets");
                IEnumerable<XElement> tilesetList = tilesets.Elements();             

                foreach (XElement t in tilesetList)
                {
                    XElement name = t.Element("Name");
                    XElement fileName = t.Element("FileName");
                    XElement tWidth = t.Element("TileWidth");
                    XElement tHeight = t.Element("TileHeight");
                    XElement setWidth = t.Element("TilesetWidth");
                    XElement setHeight = t.Element("TilesetHeight");

                    if (name != null && fileName != null && tWidth != null && tHeight != null && setWidth != null && setHeight != null)
                    {
                        TileSet imported = new TileSet(name.Value, fileName.Value, filePath + fileName.Value,
                                                       new Size(Convert.ToInt32(setWidth.Value), Convert.ToInt32(setHeight.Value)), 
                                                       new Size(Convert.ToInt32(tWidth.Value), Convert.ToInt32(tHeight.Value)), TM.LoadTexture(filePath + fileName.Value, 0));
                        tileSets.Add(imported);
                    }
                }

                XElement coords = tileLayer.Element("Coordinates");
                IEnumerable<XElement> coordList = coords.Elements();

                int x = 0;
                int y = 0;

                foreach (XElement c in coordList)
                {
                    if (y >= mapHeight)
                    {
                        ++x;
                        y = 0;
                    }

                    XElement xCoord = c.Element("xCoordinate");
                    XElement yCoord = c.Element("yCoordinate");
                    XElement id = c.Element("TilesetID");

                    if (xCoord != null && yCoord != null && id != null )
                    {
                        Point p = new Point(Convert.ToInt32(xCoord.Value), Convert.ToInt32(yCoord.Value));
                        int tilesetID = Convert.ToInt32(id.Value);

                        Tile t;

                        if (tilesetID != -1)
                        {
                            t = new Tile(p, tileSets[tilesetID].textureID);
                        }
                        else
                        {
                            t = new Tile(p, -1);
                        }
                        map.mapMatrix[x, y] = t;
                        map.tilesetIndex[x, y] = tilesetID;
           
                        ++y;
                    }                   
                }

                XElement objLayer = root.Element("ObjectLayer");
                XElement availableObjs = objLayer.Element("AvaialbleObjects");
                IEnumerable<XElement> objList = availableObjs.Elements();

                foreach (XElement o in objList)
                {
                    XElement name = o.Element("Name");
                    XElement fileName = o.Element("FileName");
                    XElement width = o.Element("Width");
                    XElement height = o.Element("Height");
                    XElement type = o.Element("Type");

                    if (name != null && fileName != null && width != null && height != null && type != null)
                    {
                        Object temp = new Object(name.Value, fileName.Value, filePath + fileName.Value, new Size(Convert.ToInt32(width.Value), Convert.ToInt32(height.Value)), new Point(0, 0), 0, Convert.ToInt32(type.Value), TM.LoadTexture(filePath + fileName.Value, 0));
                        availableObjects.Add(temp);
                    }
                }

                XElement propObjs = objLayer.Element("Props");
                IEnumerable<XElement> propList = propObjs.Elements();

                foreach (XElement p in propList)
                {
                    XElement name = p.Element("Name");
                    XElement fileName = p.Element("FileName");
                    XElement width = p.Element("Width");
                    XElement height = p.Element("Height");
                    XElement type = p.Element("Type");
                    XElement posX = p.Element("PositionX");
                    XElement posY = p.Element("PositionY");
                    XElement rotation = p.Element("Rotation");

                    if (name != null && fileName != null && width != null && height != null && type != null && posX != null && posY != null && rotation != null)
                    {                       
                        Object temp = new Object(name.Value, fileName.Value, filePath + fileName.Value, new Size(Convert.ToInt32(width.Value),
                                                 Convert.ToInt32(height.Value)), new Point(Convert.ToInt32(posX.Value), Convert.ToInt32(posY.Value)),
                                                 Convert.ToInt32(rotation.Value), Convert.ToInt32(type.Value), TM.LoadTexture(filePath + fileName.Value, 0));
                        
                        props.Add(temp);
                    }
                }

                XElement enemyObjs = objLayer.Element("Enemies");
                IEnumerable<XElement> enemyList = enemyObjs.Elements();

                foreach (XElement p in enemyList)
                {
                    XElement name = p.Element("Name");
                    XElement fileName = p.Element("FileName");
                    XElement width = p.Element("Width");
                    XElement height = p.Element("Height");
                    XElement type = p.Element("Type");
                    XElement posX = p.Element("PositionX");
                    XElement posY = p.Element("PositionY");
                    XElement rotation = p.Element("Rotation");

                    if (name != null && fileName != null && width != null && height != null && type != null && posX != null && posY != null && rotation != null)
                    {                      
                        Object temp = new Object(name.Value, fileName.Value, filePath + fileName.Value, new Size(Convert.ToInt32(width.Value),
                                                 Convert.ToInt32(height.Value)), new Point(Convert.ToInt32(posX.Value), Convert.ToInt32(posY.Value)),
                                                 Convert.ToInt32(rotation.Value), Convert.ToInt32(type.Value), TM.LoadTexture(filePath + fileName.Value, 0));

                        enemies.Add(temp);
                    }
                }

                XElement powerupObjs = objLayer.Element("Powerups");
                IEnumerable<XElement> powerList = powerupObjs.Elements();

                foreach (XElement p in powerList)
                {
                    XElement name = p.Element("Name");
                    XElement fileName = p.Element("FileName");
                    XElement width = p.Element("Width");
                    XElement height = p.Element("Height");
                    XElement type = p.Element("Type");
                    XElement posX = p.Element("PositionX");
                    XElement posY = p.Element("PositionY");
                    XElement rotation = p.Element("Rotation");

                    if (name != null && fileName != null && width != null && height != null && type != null && posX != null && posY != null && rotation != null)
                    {                     
                        Object temp = new Object(name.Value, fileName.Value, filePath + fileName.Value, new Size(Convert.ToInt32(width.Value),
                                                 Convert.ToInt32(height.Value)), new Point(Convert.ToInt32(posX.Value), Convert.ToInt32(posY.Value)),
                                                 Convert.ToInt32(rotation.Value), Convert.ToInt32(type.Value), TM.LoadTexture(filePath + fileName.Value, 0));

                        powerups.Add(temp);
                    }
                }

                XElement triggers = root.Element("TriggerLayer");
                XElement events = triggers.Element("EventTriggers");
                IEnumerable<XElement> eventList = events.Elements();

                foreach (XElement eve in eventList)
                {
                    XElement name = eve.Element("EventName");
                    XElement posX = eve.Element("PositionX");
                    XElement posY = eve.Element("PositionY");
                    XElement width = eve.Element("Width");
                    XElement height = eve.Element("Height");
                    XElement repeat = eve.Element("Repeatable");
                    XElement id = eve.Element("ID");

                    if (name != null && repeat != null && width != null && height != null && posX != null && posY != null && id != null)
                    {
                        EventTrigger temp = new EventTrigger(name.Value, new Point(Convert.ToInt32(posX.Value), Convert.ToInt32(posY.Value)),
                                                             new Size(Convert.ToInt32(width.Value), Convert.ToInt32(height.Value)), Convert.ToInt32(id.Value));

                        temp.isRepeatable = Convert.ToBoolean(repeat.Value);

                        eventTriggers.Add(temp);

                        string comboText = name.Value;

                        EventComboBox.Items.Add(comboText);
                        EventComboBox.SelectedIndex = 0;
                        
                    }
                }

                XElement collisions = triggers.Element("CollisionTriggers");
                IEnumerable<XElement> colList = collisions.Elements();

                foreach (XElement col in colList)
                {
                    XElement name = col.Element("EventName");
                    XElement posX = col.Element("PositionX");
                    XElement posY = col.Element("PositionY");
                    XElement width = col.Element("Width");
                    XElement height = col.Element("Height");
                    XElement id = col.Element("ID");

                    if (name != null && width != null && height != null && posX != null && posY != null && id != null)
                    {
                        Trigger temp = new Trigger(name.Value, new Point(Convert.ToInt32(posX.Value), Convert.ToInt32(posY.Value)),
                                                             new Size(Convert.ToInt32(width.Value), Convert.ToInt32(height.Value)), Convert.ToInt32(id.Value));

                        collisionTriggers.Add(temp);

                        string comboText = name.Value + " " + Convert.ToInt32(id.Value);

                        CollisionComboBox.Items.Add(comboText);
                        CollisionComboBox.SelectedIndex = 0;
                        collisionCount = Convert.ToInt32(id.Value);
                    }
                }

                XElement spawns = triggers.Element("SpawnTriggers");
                IEnumerable<XElement> spawnList = spawns.Elements();

                foreach (XElement spn in spawnList)
                {
                    XElement name = spn.Element("EventName");
                    XElement posX = spn.Element("PositionX");
                    XElement posY = spn.Element("PositionY");
                    XElement width = spn.Element("Width");
                    XElement height = spn.Element("Height");
                    XElement spawnX = spn.Element("SpawnPointX");
                    XElement spawnY = spn.Element("SpawnPointY");

                    XElement id = spn.Element("ID");

                    if (name != null && width != null && height != null && posX != null && posY != null && id != null && spawnX != null && spawnY != null)
                    {
                        SpawnTrigger temp = new SpawnTrigger(new Point(Convert.ToInt32(spawnX.Value), Convert.ToInt32(spawnY.Value)), 
                                                             new Size(TM.GetTextureWidth(spawnPoint), TM.GetTextureHeight(spawnPoint)),
                                                             name.Value, new Point(Convert.ToInt32(posX.Value), Convert.ToInt32(posY.Value)),
                                                             new Size(Convert.ToInt32(width.Value), Convert.ToInt32(height.Value)), Convert.ToInt32(id.Value));

                        spawnTriggers.Add(temp);


                        string comboText = name.Value;

                        SpawnComboBox.Items.Add(comboText);
                        SpawnComboBox.SelectedIndex = 0;
                    }
                }

                XElement player = triggers.Element("PlayerSpawns");
                IEnumerable<XElement> playerList = player.Elements();

                foreach (XElement ply in playerList)
                {
                    XElement num = ply.Element("PlayerNum");
                    XElement posX = ply.Element("PositionX");
                    XElement posY = ply.Element("PositionY");

                    if (posX != null && posY != null && num != null)
                    {
                        SpawnPoint temp = new SpawnPoint(new Point(Convert.ToInt32(posX.Value), Convert.ToInt32(posY.Value)), Convert.ToInt32(num.Value));

                        playerSpawnPoints.Add(temp);
                        
                        string comboText = "Player " + Convert.ToInt32(num.Value);

                        PlayerSpawnComboBox.Items.Add(comboText);
                        PlayerSpawnComboBox.SelectedIndex = 0;                    
                    }
                }

                XElement lightLayer = root.Element("LightLayer");
                XElement allLights = lightLayer.Element("Lights");
                IEnumerable<XElement> lightList = allLights.Elements();

                foreach (XElement lte in lightList)
                {
                    XElement colorR = lte.Element("Red");
                    XElement colorG = lte.Element("Green");
                    XElement colorB = lte.Element("Blue");

                    XElement posX = lte.Element("PositionX");
                    XElement posY = lte.Element("PositionY");
                    XElement intensity = lte.Element("Intensity");
                    XElement radius = lte.Element("Radius");

                    if (posX != null && posY != null && colorR != null && colorG != null && colorB != null && intensity != null && radius != null)
                    {
                        Light temp = new Light();

                        Color tempColor = Color.FromArgb(Convert.ToInt32(colorR.Value), Convert.ToInt32(colorG.Value), Convert.ToInt32(colorB.Value));

                        temp.color = tempColor.ToArgb();
                        temp.positionX = Convert.ToInt32(posX.Value);
                        temp.positionY = Convert.ToInt32(posY.Value);
                        temp.intensity = (float)Convert.ToDouble(intensity.Value);
                        temp.radius = (float)Convert.ToDouble(radius.Value);

                        lights.Add(temp);
                    }
                }

                XElement ambient = lightLayer.Element("AmbientLight");

                if (ambient != null)
                {
                    XElement r = ambient.Element("R");
                    XElement g = ambient.Element("G");
                    XElement b = ambient.Element("B");
                    XElement intensity = ambient.Element("Intensity");

                    if (r != null && g != null && b != null && intensity != null)
                    {
                        ambientColor[0] = (float)Convert.ToDouble(r.Value);
                        ambientColor[1] = (float)Convert.ToDouble(g.Value);
                        ambientColor[2] = (float)Convert.ToDouble(b.Value);
                        ambientIntensity = (float)Convert.ToDouble(intensity.Value);
                    }
                }

                if (tileSets.Count() > 0)
                {                    
                    TileWidthUpDown1.Value = tileSets[selectedTileset].tileSize.Width;
                    TileHeightUpDown1.Value = tileSets[selectedTileset].tileSize.Width;
                    TilesetNameBox.Text = tileSets[selectedTileset].name;
                }

                TileLayer.Panel1.Invalidate();
                TileLayer2.Panel2.Invalidate();
                ObjectViewSplit.Panel1.Invalidate();
                MapSplit.Panel2.Invalidate();

            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            String message = "Any unsaved information will be lost.\nAre you sure you want to create a new level?";

            RemoveDialog dlg = new RemoveDialog(message);
            dlg.Text = "New";

            if (DialogResult.OK == dlg.ShowDialog())
            {
                availableObjects.Clear();
                props.Clear();
                enemies.Clear();
                powerups.Clear();
                tileSets.Clear();
                eventTriggers.Clear();
                spawnTriggers.Clear();
                collisionTriggers.Clear();
                playerSpawnPoints.Clear();
                lights.Clear();
                EventComboBox.Items.Clear();
                SpawnComboBox.Items.Clear();
                CollisionComboBox.Items.Clear();
                PlayerSpawnComboBox.Items.Clear();

                ambientColor[0] = 1.0f;
                ambientColor[1] = 1.0f;
                ambientColor[2] = 1.0f;
                ambientIntensity = 1.0f;

                selectedProp = -1;
                selectedEnemy = -1;
                selectedPowerup = -1;

                for (int x = 0; x < mapWidth; ++x)
                {
                    for (int y = 0; y < mapHeight; ++y)
                    {
                        map.mapMatrix[x, y].tile = new Point(-1, -1);
                        map.mapMatrix[x, y].tileSetID = -1;
                        map.tilesetIndex[x, y] = -1;
                    }
                }

                MapResize();

                TileWidthUpDown1.Value = 1;
                TileHeightUpDown1.Value = 1;
                TilesetNameBox.Text = "";

                EditObjectXUpDown.Maximum = mapWidth * tileWidth;
                EditObjectYUpDown.Maximum = mapHeight * tileHeight;

                AppContainer.Panel1.AutoScrollMinSize = new Size(mapWidth * tileWidth, mapHeight * tileHeight);

                MapTab.SelectedIndex = 0;

                MapSplit.Panel2.Invalidate();
                ObjectViewSplit.Panel1.Invalidate();
                TileLayer.Panel1.Invalidate();
                TileLayer2.Panel2.Invalidate();
            }

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            String message = "Any unsaved information will be lost.\nAre you sure you want to quit?";

            RemoveDialog dlg = new RemoveDialog(message);
            dlg.Text = "Quit";

            if (DialogResult.OK == dlg.ShowDialog())
            {
                this.Close();
            }
        }

        ///////////////////////
        ////// TRIGGERS ///////
        ///////////////////////
        private void AddTriggerButton_Click(object sender, EventArgs e)
        {
            AddTriggerButton.Checked = true;
            SelectTriggerButton.Checked = false;
        }

        private void SelectTriggerButton_Click(object sender, EventArgs e)
        {
            SelectTriggerButton.Checked = true;
            AddTriggerButton.Checked = false;
        }

        private void CollisionComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            CollisionXUpDown.Value = collisionTriggers[CollisionComboBox.SelectedIndex].position.X;
            CollisionYUpDown.Value = collisionTriggers[CollisionComboBox.SelectedIndex].position.Y;
            CollisionWidthUpDown.Value = collisionTriggers[CollisionComboBox.SelectedIndex].size.Width;
            CollisionHeightUpDown.Value = collisionTriggers[CollisionComboBox.SelectedIndex].size.Height;
        }

        private void CollisionXUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (collisionTriggers.Count() > 0)
            {
                collisionTriggers[CollisionComboBox.SelectedIndex].position.X = (int)CollisionXUpDown.Value;
            }
        }

        private void CollisionYUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (collisionTriggers.Count() > 0)
            {
                collisionTriggers[CollisionComboBox.SelectedIndex].position.Y = (int)CollisionYUpDown.Value;
            }
        }

        private void CollisionWidthUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (collisionTriggers.Count() > 0)
            {
                collisionTriggers[CollisionComboBox.SelectedIndex].size.Width = (int)CollisionWidthUpDown.Value;
            }
        }

        private void CollisionHeightUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (collisionTriggers.Count() > 0)
            {
                collisionTriggers[CollisionComboBox.SelectedIndex].size.Height = (int)CollisionHeightUpDown.Value;
            }
        }

        private void CollisionTrigGroupBox_Resize(object sender, EventArgs e)
        {
            CollisionXUpDown.Width = CollisionTrigGroupBox.Right - CollisionXUpDown.Left - 10;
            CollisionYUpDown.Width = CollisionTrigGroupBox.Right - CollisionXUpDown.Left - 10;
            CollisionWidthUpDown.Width = CollisionTrigGroupBox.Right - CollisionXUpDown.Left - 10;
            CollisionHeightUpDown.Width = CollisionTrigGroupBox.Right - CollisionXUpDown.Left - 10;
        }

        private void EventComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            EventTextBox.Text = eventTriggers[EventComboBox.SelectedIndex].eventName;
            EventXUpDown.Value = eventTriggers[EventComboBox.SelectedIndex].position.X;
            EventYUpDown.Value = eventTriggers[EventComboBox.SelectedIndex].position.Y;
            EventWidthUpDown.Value = eventTriggers[EventComboBox.SelectedIndex].size.Width;
            EventHeightUpDown.Value = eventTriggers[EventComboBox.SelectedIndex].size.Height;
            RepeatCheckBox.Checked = eventTriggers[EventComboBox.SelectedIndex].isRepeatable;
        }

        private void EventTextBox_TextChanged(object sender, EventArgs e)
        {
            if (eventTriggers.Count() > 0)
            {
                eventTriggers[EventComboBox.SelectedIndex].eventName = EventTextBox.Text;
                EventComboBox.Items[EventComboBox.SelectedIndex] = EventTextBox.Text;
            }
        }

        private void EventXUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (eventTriggers.Count() > 0)
            {
                eventTriggers[EventComboBox.SelectedIndex].position.X = (int)EventXUpDown.Value;
            }
        }

        private void EventYUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (eventTriggers.Count() > 0)
            {
                eventTriggers[EventComboBox.SelectedIndex].position.Y = (int)EventYUpDown.Value;
            }
        }

        private void EventWidthUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (eventTriggers.Count() > 0)
            {
                eventTriggers[EventComboBox.SelectedIndex].size.Width = (int)EventWidthUpDown.Value;
            }
        }

        private void EventHeightUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (eventTriggers.Count() > 0)
            {
                eventTriggers[EventComboBox.SelectedIndex].size.Height = (int)EventHeightUpDown.Value;
            }
        }

        private void EventTrigGroupBox_Resize(object sender, EventArgs e)
        {
            EventTextBox.Width = EventTrigGroupBox.Right - EventXUpDown.Left - 10;
            EventXUpDown.Width = EventTrigGroupBox.Right - EventXUpDown.Left - 10;
            EventYUpDown.Width = EventTrigGroupBox.Right - EventXUpDown.Left - 10;
            EventWidthUpDown.Width = EventTrigGroupBox.Right - EventXUpDown.Left - 10;
            EventHeightUpDown.Width = EventTrigGroupBox.Right - EventXUpDown.Left - 10;
        }

        private void SpawnXUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (spawnTriggers.Count() > 0)
            {
                spawnTriggers[SpawnComboBox.SelectedIndex].spawnPoint.X = (int)SpawnXUpDown.Value;
            }
        }

        private void SpawnYUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (spawnTriggers.Count() > 0)
            {
                spawnTriggers[SpawnComboBox.SelectedIndex].spawnPoint.Y = (int)SpawnYUpDown.Value;
            }
        }

        private void SpawnTrigHeightUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (spawnTriggers.Count() > 0)
            {
                spawnTriggers[SpawnComboBox.SelectedIndex].size.Height = (int)SpawnTrigHeightUpDown.Value;
            }
        }

        private void SpawnTrigXUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (spawnTriggers.Count() > 0)
            {
                spawnTriggers[SpawnComboBox.SelectedIndex].position.X = (int)SpawnTrigXUpDown.Value;
            }
        }

        private void SpawnTrigYUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (spawnTriggers.Count() > 0)
            {
                spawnTriggers[SpawnComboBox.SelectedIndex].position.Y = (int)SpawnTrigYUpDown.Value;
            }
        }

        private void SpawnTrigWidthUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (spawnTriggers.Count() > 0)
            {
                spawnTriggers[SpawnComboBox.SelectedIndex].size.Width = (int)SpawnTrigWidthUpDown.Value;
            }
        }

        private void RepeatCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (eventTriggers.Count() > 0)
            {
                eventTriggers[EventComboBox.SelectedIndex].isRepeatable = RepeatCheckBox.Checked;
            }
        }

        private void SpawnTrigGroupBox_Resize(object sender, EventArgs e)
        {
            SpawnXUpDown.Width = SpawnTrigGroupBox.Right - SpawnXUpDown.Left - 10;
            SpawnYUpDown.Width = SpawnTrigGroupBox.Right - SpawnXUpDown.Left - 10;
            SpawnTrigXUpDown.Width = SpawnTrigGroupBox.Right - SpawnXUpDown.Left - 10;
            SpawnTrigYUpDown.Width = SpawnTrigGroupBox.Right - SpawnXUpDown.Left - 10;
            SpawnTrigWidthUpDown.Width = SpawnTrigGroupBox.Right - SpawnXUpDown.Left - 10;
            SpawnTrigHeightUpDown.Width = SpawnTrigGroupBox.Right - SpawnXUpDown.Left - 10;
        }

        private void PlayerSpawnXUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (playerSpawnPoints.Count() > 0)
            {
                playerSpawnPoints[PlayerSpawnComboBox.SelectedIndex].position.X = (int)PlayerSpawnXUpDown.Value;
            }
            
        }

        private void PlayerSpawnYUpDown_ValueChanged(object sender, EventArgs e)
        {
              if (playerSpawnPoints.Count() > 0)
              {
                  playerSpawnPoints[PlayerSpawnComboBox.SelectedIndex].position.Y = (int)PlayerSpawnYUpDown.Value;
              }
        }

        private void PlayerSpawnGroupBox_Resize(object sender, EventArgs e)
        {
            PlayerSpawnYUpDown.Width = PlayerSpawnGroupBox.Right - PlayerSpawnYUpDown.Left - 10;
            PlayerSpawnXUpDown.Width = PlayerSpawnGroupBox.Right - PlayerSpawnXUpDown.Left - 10;
        }

        ///////////////////////
        ////// LIGHTING ///////
        ///////////////////////
        private void ambientIntensityNumeric_ValueChanged(object sender, EventArgs e)
        {
            ambientIntensity = (float)ambientIntensityNumeric.Value;
        }

        private void ambientColorButton_Click(object sender, EventArgs e)
        {
            ColorDialog dlg = new ColorDialog();

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                ambientColorButton.BackColor = dlg.Color;
                ambientColor[0] = (float)dlg.Color.R / (float)255;
                ambientColor[1] = (float)dlg.Color.G / (float)255;
                ambientColor[2] = (float)dlg.Color.B / (float)255;
            }
        }

        private void lightIntensityRadiusNumeric_ValueChanged(object sender, EventArgs e)
        {
            if (lightSelected != -1)
            {
                lights[lightSelected].radius = (float)lightIntensityRadiusNumeric.Value;
            }
        }

        private void lightPositionYNumeric_ValueChanged(object sender, EventArgs e)
        {
            if (lightSelected != -1)
            {
                lights[lightSelected].positionY = (float)lightPositionYNumeric.Value;
            }
        }

        private void lightIntensityNumeric_ValueChanged(object sender, EventArgs e)
        {
            if (lightSelected != -1)
            {
                lights[lightSelected].intensity = (float)lightIntensityNumeric.Value;
            }
        }

        private void lightColorButton_Click(object sender, EventArgs e)
        {
            ColorDialog dlg = new ColorDialog();

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                lightColorButton.BackColor = dlg.Color;
                if (lightSelected != -1)
                    lights[lightSelected].color = dlg.Color.ToArgb();
            }
        }

        private void lightPositionXNumeric_ValueChanged(object sender, EventArgs e)
        {
            if (lightSelected != -1)
            {
                lights[lightSelected].positionX = (float)lightPositionXNumeric.Value;
            }
        }

        private void lightPlacementButton_Click(object sender, EventArgs e)
        {
            selectedSourceTile = new Point(-1, -1);
            PaintBrushButton.Checked = false;
            PaintBucketButton.Checked = false;
            EraserButton.Checked = false;
            SelectTileButton.Checked = false;
            PlaceObjectButton.Checked = false;
            SelectObjectButton.Checked = false;
            AppContainer.Panel1.Cursor = Cursors.Arrow;
            selectedObject = -1;
            lightSelected = -1;
            lightToolSelected = true;
        }

        void lightPlacement(MouseEventArgs e)
        {
            Point offset = e.Location;

            offset.X -= AppContainer.Panel1.AutoScrollPosition.X;
            offset.Y -= AppContainer.Panel1.AutoScrollPosition.Y;

            Rectangle mouseRay = new Rectangle(offset.X, offset.Y, 1, 1);
            Rectangle lightPos = Rectangle.Empty;

            lightSelected = -1;
            int tempLightSelected = -1;

            for (int i = 0; i < lights.Count; ++i)
            {
                lightPos = new Rectangle(((int)lights[i].positionX) - 43, ((int)lights[i].positionY) - 43, 86, 86);

                if (lightPos.IntersectsWith(mouseRay))
                    tempLightSelected = i;
            }
            if (tempLightSelected == -1)
            {
                Light light = new Light();

                light.intensity = (float)lightIntensityNumeric.Value;
                light.color = lightColorButton.BackColor.ToArgb();
                light.radius = (float)lightIntensityRadiusNumeric.Value;
                light.positionX = offset.X;
                light.positionY = offset.Y;

                lights.Add(light);
            }
            else
            {
                Light light = lights[tempLightSelected];
                lightIntensityNumeric.Value = (decimal)light.intensity;
                lightColorButton.BackColor = Color.FromArgb(light.color);
                lightIntensityRadiusNumeric.Value = (decimal)light.radius;
                lightPositionXNumeric.Value = (decimal)light.positionX;
                lightPositionYNumeric.Value = (decimal)light.positionY;
                lightSelected = tempLightSelected;
            }
        }

        private void DrawLights()
        {
            Point offset = new Point(43, 43);
            offset.X -= AppContainer.Panel1.AutoScrollPosition.X;
            offset.Y -= AppContainer.Panel1.AutoScrollPosition.Y;

            for (int i = 0; i < lights.Count; ++i)
            {
                TM.Draw(lightIconID, (int)(lights[i].positionX) - offset.X, (int)(lights[i].positionY) - offset.Y, 0.3f, 0.3f, Rectangle.Empty, 0, 0, 0.0f, 0);
            }

            if (lightSelected != -1)
                TM.Draw(lightSelectedIconID, (int)(lights[lightSelected].positionX) - offset.X, (int)(lights[lightSelected].positionY) - offset.Y, 0.3f, 0.3f, Rectangle.Empty, 0, 0, 0.0f, 0);
        }

        private void LightsVisible()
        {
            Point offset = new Point(0, 0);
            offset.X -= AppContainer.Panel1.AutoScrollPosition.X;
            offset.Y -= AppContainer.Panel1.AutoScrollPosition.Y;

            if (lights.Count() < 10)
            {
                for (int i = 0; i < lights.Count; ++i)
                    visibleLight[i].lightIntensity = 0.0f;
            }
            else
            {
                for (int i = 0; i < 10; ++i)
                    visibleLight[i].lightIntensity = 0.0f;
            }

            Rectangle screen = new Rectangle(offset.X-200, offset.Y-200, AppContainer.Panel1.Width+200, AppContainer.Panel1.Height+200);
            Rectangle lightPos = Rectangle.Empty;
            int currentLight = 0;
            for (int i = 0; i < lights.Count; ++i)
            {
                lightPos = new Rectangle(((int)lights[i].positionX) - 1, ((int)lights[i].positionY) - 1, 2, 2);

                if (lightPos.IntersectsWith(screen))
                {
                    if (currentLight < 10)
                    {
                        visibleLight[currentLight].lightPos[0] = (lights[i].positionX - offset.X) / ((float)AppContainer.Panel1.Width);
                        visibleLight[currentLight].lightPos[1] = (lights[i].positionY - offset.Y) / ((float)AppContainer.Panel1.Height);
                        visibleLight[currentLight].lightIntensity = lights[i].intensity;
                        visibleLight[currentLight].lightRadius[0] = lights[i].radius / ((float)AppContainer.Panel1.Width);
                        visibleLight[currentLight].lightRadius[1] = lights[i].radius / ((float)AppContainer.Panel1.Width);

                        Color color = Color.FromArgb(lights[i].color);

                        visibleLight[currentLight].lightColor[0] = (float)color.R / (float)255;
                        visibleLight[currentLight].lightColor[1] = (float)color.G / (float)255;
                        visibleLight[currentLight].lightColor[2] = (float)color.B / (float)255;

                        currentLight++;
                    }
                }

            }
        }

        private void ToggleCollisionContext_Click(object sender, EventArgs e)
        {
            ToggleCollisionContext.Checked = !ToggleCollisionContext.Checked;
        }

        private void ToggleEventContext_Click(object sender, EventArgs e)
        {
            ToggleEventContext.Checked = !ToggleEventContext.Checked;
        }

        private void ToggleSpawnContext_Click(object sender, EventArgs e)
        {
            ToggleSpawnContext.Checked = !ToggleSpawnContext.Checked;
        }

    }
}
